diff options
author | pre-commit run by Even Rouault <even.rouault-bot@spatialys.com> | 2022-12-08 19:18:55 +0100 |
---|---|---|
committer | Even Rouault <even.rouault@spatialys.com> | 2022-12-08 19:18:55 +0100 |
commit | 42173d6ace476b5228d866640b5355f74e5a108d (patch) | |
tree | 5be985b2d2b6cbcbf16fbc569da33bd709f99f4a | |
parent | 5e6a5fd6fac2007f553ea2753d39bf56875f3d09 (diff) | |
download | libtiff-git-42173d6ace476b5228d866640b5355f74e5a108d.tar.gz |
Reformatting in libtiff/ using 'pre-commit run'
55 files changed, 38691 insertions, 35591 deletions
diff --git a/libtiff/mkg3states.c b/libtiff/mkg3states.c index ca5b328b..f32113a3 100644 --- a/libtiff/mkg3states.c +++ b/libtiff/mkg3states.c @@ -2,23 +2,23 @@ * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -27,390 +27,214 @@ * in Frank Cringle's viewfax program; * Copyright (C) 1990, 1995 Frank D. Cringle. */ -#include "tif_config.h" #include "libport.h" +#include "tif_config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef HAVE_UNISTD_H -# include <unistd.h> +#include <unistd.h> #endif #include "tif_fax3.h" -#define streq(a,b) (strcmp(a,b) == 0) +#define streq(a, b) (strcmp(a, b) == 0) /* NB: can't use names in tif_fax3.h 'cuz they are declared const */ TIFFFaxTabEnt MainTable[128]; TIFFFaxTabEnt WhiteTable[4096]; TIFFFaxTabEnt BlackTable[8192]; -struct proto { - uint16_t code; /* right justified, lsb-first, zero filled */ - uint16_t val; /* (pixel count)<<4 + code width */ +struct proto +{ + uint16_t code; /* right justified, lsb-first, zero filled */ + uint16_t val; /* (pixel count)<<4 + code width */ }; -static struct proto Pass[] = { -{ 0x0008, 4 }, -{ 0, 0 } -}; +static struct proto Pass[] = {{0x0008, 4}, {0, 0}}; -static struct proto Horiz[] = { -{ 0x0004, 3 }, -{ 0, 0 } -}; +static struct proto Horiz[] = {{0x0004, 3}, {0, 0}}; -static struct proto V0[] = { -{ 0x0001, 1 }, -{ 0, 0 } -}; +static struct proto V0[] = {{0x0001, 1}, {0, 0}}; -static struct proto VR[] = { -{ 0x0006, (1<<4)+3 }, -{ 0x0030, (2<<4)+6 }, -{ 0x0060, (3<<4)+7 }, -{ 0, 0 } -}; +static struct proto VR[] = {{0x0006, (1 << 4) + 3}, + {0x0030, (2 << 4) + 6}, + {0x0060, (3 << 4) + 7}, + {0, 0}}; -static struct proto VL[] = { -{ 0x0002, (1<<4)+3 }, -{ 0x0010, (2<<4)+6 }, -{ 0x0020, (3<<4)+7 }, -{ 0, 0 } -}; +static struct proto VL[] = {{0x0002, (1 << 4) + 3}, + {0x0010, (2 << 4) + 6}, + {0x0020, (3 << 4) + 7}, + {0, 0}}; -static struct proto Ext[] = { -{ 0x0040, 7 }, -{ 0, 0 } -}; +static struct proto Ext[] = {{0x0040, 7}, {0, 0}}; -static struct proto EOLV[] = { -{ 0x0000, 7 }, -{ 0, 0 } -}; +static struct proto EOLV[] = {{0x0000, 7}, {0, 0}}; static struct proto MakeUpW[] = { -{ 0x001b, 1029 }, -{ 0x0009, 2053 }, -{ 0x003a, 3078 }, -{ 0x0076, 4103 }, -{ 0x006c, 5128 }, -{ 0x00ec, 6152 }, -{ 0x0026, 7176 }, -{ 0x00a6, 8200 }, -{ 0x0016, 9224 }, -{ 0x00e6, 10248 }, -{ 0x0066, 11273 }, -{ 0x0166, 12297 }, -{ 0x0096, 13321 }, -{ 0x0196, 14345 }, -{ 0x0056, 15369 }, -{ 0x0156, 16393 }, -{ 0x00d6, 17417 }, -{ 0x01d6, 18441 }, -{ 0x0036, 19465 }, -{ 0x0136, 20489 }, -{ 0x00b6, 21513 }, -{ 0x01b6, 22537 }, -{ 0x0032, 23561 }, -{ 0x0132, 24585 }, -{ 0x00b2, 25609 }, -{ 0x0006, 26630 }, -{ 0x01b2, 27657 }, -{ 0, 0 } -}; + {0x001b, 1029}, {0x0009, 2053}, {0x003a, 3078}, {0x0076, 4103}, + {0x006c, 5128}, {0x00ec, 6152}, {0x0026, 7176}, {0x00a6, 8200}, + {0x0016, 9224}, {0x00e6, 10248}, {0x0066, 11273}, {0x0166, 12297}, + {0x0096, 13321}, {0x0196, 14345}, {0x0056, 15369}, {0x0156, 16393}, + {0x00d6, 17417}, {0x01d6, 18441}, {0x0036, 19465}, {0x0136, 20489}, + {0x00b6, 21513}, {0x01b6, 22537}, {0x0032, 23561}, {0x0132, 24585}, + {0x00b2, 25609}, {0x0006, 26630}, {0x01b2, 27657}, {0, 0}}; static struct proto MakeUpB[] = { -{ 0x03c0, 1034 }, -{ 0x0130, 2060 }, -{ 0x0930, 3084 }, -{ 0x0da0, 4108 }, -{ 0x0cc0, 5132 }, -{ 0x02c0, 6156 }, -{ 0x0ac0, 7180 }, -{ 0x06c0, 8205 }, -{ 0x16c0, 9229 }, -{ 0x0a40, 10253 }, -{ 0x1a40, 11277 }, -{ 0x0640, 12301 }, -{ 0x1640, 13325 }, -{ 0x09c0, 14349 }, -{ 0x19c0, 15373 }, -{ 0x05c0, 16397 }, -{ 0x15c0, 17421 }, -{ 0x0dc0, 18445 }, -{ 0x1dc0, 19469 }, -{ 0x0940, 20493 }, -{ 0x1940, 21517 }, -{ 0x0540, 22541 }, -{ 0x1540, 23565 }, -{ 0x0b40, 24589 }, -{ 0x1b40, 25613 }, -{ 0x04c0, 26637 }, -{ 0x14c0, 27661 }, -{ 0, 0 } -}; + {0x03c0, 1034}, {0x0130, 2060}, {0x0930, 3084}, {0x0da0, 4108}, + {0x0cc0, 5132}, {0x02c0, 6156}, {0x0ac0, 7180}, {0x06c0, 8205}, + {0x16c0, 9229}, {0x0a40, 10253}, {0x1a40, 11277}, {0x0640, 12301}, + {0x1640, 13325}, {0x09c0, 14349}, {0x19c0, 15373}, {0x05c0, 16397}, + {0x15c0, 17421}, {0x0dc0, 18445}, {0x1dc0, 19469}, {0x0940, 20493}, + {0x1940, 21517}, {0x0540, 22541}, {0x1540, 23565}, {0x0b40, 24589}, + {0x1b40, 25613}, {0x04c0, 26637}, {0x14c0, 27661}, {0, 0}}; static struct proto MakeUp[] = { -{ 0x0080, 28683 }, -{ 0x0180, 29707 }, -{ 0x0580, 30731 }, -{ 0x0480, 31756 }, -{ 0x0c80, 32780 }, -{ 0x0280, 33804 }, -{ 0x0a80, 34828 }, -{ 0x0680, 35852 }, -{ 0x0e80, 36876 }, -{ 0x0380, 37900 }, -{ 0x0b80, 38924 }, -{ 0x0780, 39948 }, -{ 0x0f80, 40972 }, -{ 0, 0 } -}; + {0x0080, 28683}, {0x0180, 29707}, {0x0580, 30731}, {0x0480, 31756}, + {0x0c80, 32780}, {0x0280, 33804}, {0x0a80, 34828}, {0x0680, 35852}, + {0x0e80, 36876}, {0x0380, 37900}, {0x0b80, 38924}, {0x0780, 39948}, + {0x0f80, 40972}, {0, 0}}; static struct proto TermW[] = { -{ 0x00ac, 8 }, -{ 0x0038, 22 }, -{ 0x000e, 36 }, -{ 0x0001, 52 }, -{ 0x000d, 68 }, -{ 0x0003, 84 }, -{ 0x0007, 100 }, -{ 0x000f, 116 }, -{ 0x0019, 133 }, -{ 0x0005, 149 }, -{ 0x001c, 165 }, -{ 0x0002, 181 }, -{ 0x0004, 198 }, -{ 0x0030, 214 }, -{ 0x000b, 230 }, -{ 0x002b, 246 }, -{ 0x0015, 262 }, -{ 0x0035, 278 }, -{ 0x0072, 295 }, -{ 0x0018, 311 }, -{ 0x0008, 327 }, -{ 0x0074, 343 }, -{ 0x0060, 359 }, -{ 0x0010, 375 }, -{ 0x000a, 391 }, -{ 0x006a, 407 }, -{ 0x0064, 423 }, -{ 0x0012, 439 }, -{ 0x000c, 455 }, -{ 0x0040, 472 }, -{ 0x00c0, 488 }, -{ 0x0058, 504 }, -{ 0x00d8, 520 }, -{ 0x0048, 536 }, -{ 0x00c8, 552 }, -{ 0x0028, 568 }, -{ 0x00a8, 584 }, -{ 0x0068, 600 }, -{ 0x00e8, 616 }, -{ 0x0014, 632 }, -{ 0x0094, 648 }, -{ 0x0054, 664 }, -{ 0x00d4, 680 }, -{ 0x0034, 696 }, -{ 0x00b4, 712 }, -{ 0x0020, 728 }, -{ 0x00a0, 744 }, -{ 0x0050, 760 }, -{ 0x00d0, 776 }, -{ 0x004a, 792 }, -{ 0x00ca, 808 }, -{ 0x002a, 824 }, -{ 0x00aa, 840 }, -{ 0x0024, 856 }, -{ 0x00a4, 872 }, -{ 0x001a, 888 }, -{ 0x009a, 904 }, -{ 0x005a, 920 }, -{ 0x00da, 936 }, -{ 0x0052, 952 }, -{ 0x00d2, 968 }, -{ 0x004c, 984 }, -{ 0x00cc, 1000 }, -{ 0x002c, 1016 }, -{ 0, 0 } -}; + {0x00ac, 8}, {0x0038, 22}, {0x000e, 36}, {0x0001, 52}, {0x000d, 68}, + {0x0003, 84}, {0x0007, 100}, {0x000f, 116}, {0x0019, 133}, {0x0005, 149}, + {0x001c, 165}, {0x0002, 181}, {0x0004, 198}, {0x0030, 214}, {0x000b, 230}, + {0x002b, 246}, {0x0015, 262}, {0x0035, 278}, {0x0072, 295}, {0x0018, 311}, + {0x0008, 327}, {0x0074, 343}, {0x0060, 359}, {0x0010, 375}, {0x000a, 391}, + {0x006a, 407}, {0x0064, 423}, {0x0012, 439}, {0x000c, 455}, {0x0040, 472}, + {0x00c0, 488}, {0x0058, 504}, {0x00d8, 520}, {0x0048, 536}, {0x00c8, 552}, + {0x0028, 568}, {0x00a8, 584}, {0x0068, 600}, {0x00e8, 616}, {0x0014, 632}, + {0x0094, 648}, {0x0054, 664}, {0x00d4, 680}, {0x0034, 696}, {0x00b4, 712}, + {0x0020, 728}, {0x00a0, 744}, {0x0050, 760}, {0x00d0, 776}, {0x004a, 792}, + {0x00ca, 808}, {0x002a, 824}, {0x00aa, 840}, {0x0024, 856}, {0x00a4, 872}, + {0x001a, 888}, {0x009a, 904}, {0x005a, 920}, {0x00da, 936}, {0x0052, 952}, + {0x00d2, 968}, {0x004c, 984}, {0x00cc, 1000}, {0x002c, 1016}, {0, 0}}; static struct proto TermB[] = { -{ 0x03b0, 10 }, -{ 0x0002, 19 }, -{ 0x0003, 34 }, -{ 0x0001, 50 }, -{ 0x0006, 67 }, -{ 0x000c, 84 }, -{ 0x0004, 100 }, -{ 0x0018, 117 }, -{ 0x0028, 134 }, -{ 0x0008, 150 }, -{ 0x0010, 167 }, -{ 0x0050, 183 }, -{ 0x0070, 199 }, -{ 0x0020, 216 }, -{ 0x00e0, 232 }, -{ 0x0030, 249 }, -{ 0x03a0, 266 }, -{ 0x0060, 282 }, -{ 0x0040, 298 }, -{ 0x0730, 315 }, -{ 0x00b0, 331 }, -{ 0x01b0, 347 }, -{ 0x0760, 363 }, -{ 0x00a0, 379 }, -{ 0x0740, 395 }, -{ 0x00c0, 411 }, -{ 0x0530, 428 }, -{ 0x0d30, 444 }, -{ 0x0330, 460 }, -{ 0x0b30, 476 }, -{ 0x0160, 492 }, -{ 0x0960, 508 }, -{ 0x0560, 524 }, -{ 0x0d60, 540 }, -{ 0x04b0, 556 }, -{ 0x0cb0, 572 }, -{ 0x02b0, 588 }, -{ 0x0ab0, 604 }, -{ 0x06b0, 620 }, -{ 0x0eb0, 636 }, -{ 0x0360, 652 }, -{ 0x0b60, 668 }, -{ 0x05b0, 684 }, -{ 0x0db0, 700 }, -{ 0x02a0, 716 }, -{ 0x0aa0, 732 }, -{ 0x06a0, 748 }, -{ 0x0ea0, 764 }, -{ 0x0260, 780 }, -{ 0x0a60, 796 }, -{ 0x04a0, 812 }, -{ 0x0ca0, 828 }, -{ 0x0240, 844 }, -{ 0x0ec0, 860 }, -{ 0x01c0, 876 }, -{ 0x0e40, 892 }, -{ 0x0140, 908 }, -{ 0x01a0, 924 }, -{ 0x09a0, 940 }, -{ 0x0d40, 956 }, -{ 0x0340, 972 }, -{ 0x05a0, 988 }, -{ 0x0660, 1004 }, -{ 0x0e60, 1020 }, -{ 0, 0 } -}; + {0x03b0, 10}, {0x0002, 19}, {0x0003, 34}, {0x0001, 50}, {0x0006, 67}, + {0x000c, 84}, {0x0004, 100}, {0x0018, 117}, {0x0028, 134}, {0x0008, 150}, + {0x0010, 167}, {0x0050, 183}, {0x0070, 199}, {0x0020, 216}, {0x00e0, 232}, + {0x0030, 249}, {0x03a0, 266}, {0x0060, 282}, {0x0040, 298}, {0x0730, 315}, + {0x00b0, 331}, {0x01b0, 347}, {0x0760, 363}, {0x00a0, 379}, {0x0740, 395}, + {0x00c0, 411}, {0x0530, 428}, {0x0d30, 444}, {0x0330, 460}, {0x0b30, 476}, + {0x0160, 492}, {0x0960, 508}, {0x0560, 524}, {0x0d60, 540}, {0x04b0, 556}, + {0x0cb0, 572}, {0x02b0, 588}, {0x0ab0, 604}, {0x06b0, 620}, {0x0eb0, 636}, + {0x0360, 652}, {0x0b60, 668}, {0x05b0, 684}, {0x0db0, 700}, {0x02a0, 716}, + {0x0aa0, 732}, {0x06a0, 748}, {0x0ea0, 764}, {0x0260, 780}, {0x0a60, 796}, + {0x04a0, 812}, {0x0ca0, 828}, {0x0240, 844}, {0x0ec0, 860}, {0x01c0, 876}, + {0x0e40, 892}, {0x0140, 908}, {0x01a0, 924}, {0x09a0, 940}, {0x0d40, 956}, + {0x0340, 972}, {0x05a0, 988}, {0x0660, 1004}, {0x0e60, 1020}, {0, 0}}; -static struct proto EOLH[] = { -{ 0x0000, 11 }, -{ 0, 0 } -}; +static struct proto EOLH[] = {{0x0000, 11}, {0, 0}}; -static void -FillTable(TIFFFaxTabEnt *T, int Size, struct proto *P, int State) +static void FillTable(TIFFFaxTabEnt *T, int Size, struct proto *P, int State) { int limit = 1 << Size; - while (P->val) { - int width = P->val & 15; - int param = P->val >> 4; - int incr = 1 << width; - int code; - for (code = P->code; code < limit; code += incr) { - TIFFFaxTabEnt *E = T+code; - E->State = State; - E->Width = width; - E->Param = param; - } - P++; + while (P->val) + { + int width = P->val & 15; + int param = P->val >> 4; + int incr = 1 << width; + int code; + for (code = P->code; code < limit; code += incr) + { + TIFFFaxTabEnt *E = T + code; + E->State = State; + E->Width = width; + E->Param = param; + } + P++; } } -static char* storage_class = ""; -static char* const_class = ""; -static int packoutput = 1; -static char* prebrace = ""; -static char* postbrace = ""; +static char *storage_class = ""; +static char *const_class = ""; +static int packoutput = 1; +static char *prebrace = ""; +static char *postbrace = ""; -void -WriteTable(FILE* fd, const TIFFFaxTabEnt* T, int Size, const char* name) +void WriteTable(FILE *fd, const TIFFFaxTabEnt *T, int Size, const char *name) { int i; - char* sep; + char *sep; - fprintf(fd, "%s %s TIFFFaxTabEnt %s[%d] = {", - storage_class, const_class, name, Size); - if (packoutput) { - sep = "\n"; - for (i = 0; i < Size; i++) { - fprintf(fd, "%s%s%d,%d,%d%s", - sep, prebrace, T->State, T->Width, (int) T->Param, postbrace); - if (((i+1) % 10) == 0) - sep = ",\n"; - else - sep = ","; - T++; - } - } else { - sep = "\n "; - for (i = 0; i < Size; i++) { - fprintf(fd, "%s%s%3d,%3d,%4d%s", - sep, prebrace, T->State, T->Width, (int) T->Param, postbrace); - if (((i+1) % 6) == 0) - sep = ",\n "; - else - sep = ","; - T++; - } + fprintf(fd, "%s %s TIFFFaxTabEnt %s[%d] = {", storage_class, const_class, + name, Size); + if (packoutput) + { + sep = "\n"; + for (i = 0; i < Size; i++) + { + fprintf(fd, "%s%s%d,%d,%d%s", sep, prebrace, T->State, T->Width, + (int)T->Param, postbrace); + if (((i + 1) % 10) == 0) + sep = ",\n"; + else + sep = ","; + T++; + } + } + else + { + sep = "\n "; + for (i = 0; i < Size; i++) + { + fprintf(fd, "%s%s%3d,%3d,%4d%s", sep, prebrace, T->State, T->Width, + (int)T->Param, postbrace); + if (((i + 1) % 6) == 0) + sep = ",\n "; + else + sep = ","; + T++; + } } fprintf(fd, "\n};\n"); } /* initialise the huffman code tables */ -int -main(int argc, char* argv[]) +int main(int argc, char *argv[]) { - FILE* fd; - char* outputfile; + FILE *fd; + char *outputfile; int c; #if !HAVE_DECL_OPTARG extern int optind; - extern char* optarg; + extern char *optarg; #endif while ((c = getopt(argc, argv, "c:s:bp")) != -1) - switch (c) { - case 'c': - const_class = optarg; - break; - case 's': - storage_class = optarg; - break; - case 'p': - packoutput = 0; - break; - case 'b': - prebrace = "{"; - postbrace = "}"; - break; - case '?': - fprintf(stderr, - "usage: %s [-c const] [-s storage] [-p] [-b] file\n", - argv[0]); - return (-1); - } + switch (c) + { + case 'c': + const_class = optarg; + break; + case 's': + storage_class = optarg; + break; + case 'p': + packoutput = 0; + break; + case 'b': + prebrace = "{"; + postbrace = "}"; + break; + case '?': + fprintf(stderr, + "usage: %s [-c const] [-s storage] [-p] [-b] file\n", + argv[0]); + return (-1); + } outputfile = optind < argc ? argv[optind] : "g3states.h"; fd = fopen(outputfile, "w"); - if (fd == NULL) { - fprintf(stderr, "%s: %s: Cannot create output file.\n", - argv[0], outputfile); - return (-2); + if (fd == NULL) + { + fprintf(stderr, "%s: %s: Cannot create output file.\n", argv[0], + outputfile); + return (-2); } FillTable(MainTable, 7, Pass, S_Pass); FillTable(MainTable, 7, Horiz, S_Horiz); diff --git a/libtiff/mkspans.c b/libtiff/mkspans.c index b82db8bc..24c63ab7 100644 --- a/libtiff/mkspans.c +++ b/libtiff/mkspans.c @@ -2,70 +2,75 @@ * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ -#include <string.h> #include <stdio.h> +#include <string.h> /* * Hack program to construct tables used to find * runs of zeros and ones in Group 3 Fax encoding. */ -dumparray(name, runs) - char *name; - unsigned char runs[256]; +dumparray(name, runs) char *name; +unsigned char runs[256]; { - int i; - char *sep; - printf("static unsigned char %s[256] = {\n", name); - sep = " "; - for (i = 0; i < 256; i++) { - printf("%s%d", sep, runs[i]); - if (((i + 1) % 16) == 0) { - printf(", /* 0x%02x - 0x%02x */\n", i-15, i); - sep = " "; - } else - sep = ", "; - } - printf("\n};\n"); + int i; + char *sep; + printf("static unsigned char %s[256] = {\n", name); + sep = " "; + for (i = 0; i < 256; i++) + { + printf("%s%d", sep, runs[i]); + if (((i + 1) % 16) == 0) + { + printf(", /* 0x%02x - 0x%02x */\n", i - 15, i); + sep = " "; + } + else + sep = ", "; + } + printf("\n};\n"); } main() { - unsigned char runs[2][256]; + unsigned char runs[2][256]; - memset(runs[0], 0, 256*sizeof (char)); - memset(runs[1], 0, 256*sizeof (char)); - { register int run, runlen, i; - runlen = 1; - for (run = 0x80; run != 0xff; run = (run>>1)|0x80) { - for (i = run-1; i >= 0; i--) { - runs[1][run|i] = runlen; - runs[0][(~(run|i)) & 0xff] = runlen; - } - runlen++; - } - runs[1][0xff] = runs[0][0] = 8; - } - dumparray("bruns", runs[0]); - dumparray("wruns", runs[1]); + memset(runs[0], 0, 256 * sizeof(char)); + memset(runs[1], 0, 256 * sizeof(char)); + { + register int run, runlen, i; + runlen = 1; + for (run = 0x80; run != 0xff; run = (run >> 1) | 0x80) + { + for (i = run - 1; i >= 0; i--) + { + runs[1][run | i] = runlen; + runs[0][(~(run | i)) & 0xff] = runlen; + } + runlen++; + } + runs[1][0xff] = runs[0][0] = 8; + } + dumparray("bruns", runs[0]); + dumparray("wruns", runs[1]); } diff --git a/libtiff/t4.h b/libtiff/t4.h index ff4e3f45..f933d4a3 100644 --- a/libtiff/t4.h +++ b/libtiff/t4.h @@ -23,26 +23,27 @@ */ #ifndef _T4_ -#define _T4_ +#define _T4_ /* * CCITT T.4 1D Huffman runlength codes and * related definitions. Given the small sizes * of these tables it does not seem * worthwhile to make code & length 8 bits. */ -typedef struct tableentry { - unsigned short length; /* bit length of g3 code */ - unsigned short code; /* g3 code */ - short runlen; /* run length in bits */ +typedef struct tableentry +{ + unsigned short length; /* bit length of g3 code */ + unsigned short code; /* g3 code */ + short runlen; /* run length in bits */ } tableentry; -#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */ +#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */ /* status values returned instead of a run length */ -#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */ -#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */ -#define G3CODE_EOF -3 /* end of input data */ -#define G3CODE_INCOMP -4 /* incomplete run code */ +#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */ +#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */ +#define G3CODE_EOF -3 /* end of input data */ +#define G3CODE_INCOMP -4 /* incomplete run code */ /* * Note that these tables are ordered such that the @@ -54,227 +55,227 @@ typedef struct tableentry { */ #ifdef G3CODES const tableentry TIFFFaxWhiteCodes[] = { - { 8, 0x35, 0 }, /* 0011 0101 */ - { 6, 0x7, 1 }, /* 0001 11 */ - { 4, 0x7, 2 }, /* 0111 */ - { 4, 0x8, 3 }, /* 1000 */ - { 4, 0xB, 4 }, /* 1011 */ - { 4, 0xC, 5 }, /* 1100 */ - { 4, 0xE, 6 }, /* 1110 */ - { 4, 0xF, 7 }, /* 1111 */ - { 5, 0x13, 8 }, /* 1001 1 */ - { 5, 0x14, 9 }, /* 1010 0 */ - { 5, 0x7, 10 }, /* 0011 1 */ - { 5, 0x8, 11 }, /* 0100 0 */ - { 6, 0x8, 12 }, /* 0010 00 */ - { 6, 0x3, 13 }, /* 0000 11 */ - { 6, 0x34, 14 }, /* 1101 00 */ - { 6, 0x35, 15 }, /* 1101 01 */ - { 6, 0x2A, 16 }, /* 1010 10 */ - { 6, 0x2B, 17 }, /* 1010 11 */ - { 7, 0x27, 18 }, /* 0100 111 */ - { 7, 0xC, 19 }, /* 0001 100 */ - { 7, 0x8, 20 }, /* 0001 000 */ - { 7, 0x17, 21 }, /* 0010 111 */ - { 7, 0x3, 22 }, /* 0000 011 */ - { 7, 0x4, 23 }, /* 0000 100 */ - { 7, 0x28, 24 }, /* 0101 000 */ - { 7, 0x2B, 25 }, /* 0101 011 */ - { 7, 0x13, 26 }, /* 0010 011 */ - { 7, 0x24, 27 }, /* 0100 100 */ - { 7, 0x18, 28 }, /* 0011 000 */ - { 8, 0x2, 29 }, /* 0000 0010 */ - { 8, 0x3, 30 }, /* 0000 0011 */ - { 8, 0x1A, 31 }, /* 0001 1010 */ - { 8, 0x1B, 32 }, /* 0001 1011 */ - { 8, 0x12, 33 }, /* 0001 0010 */ - { 8, 0x13, 34 }, /* 0001 0011 */ - { 8, 0x14, 35 }, /* 0001 0100 */ - { 8, 0x15, 36 }, /* 0001 0101 */ - { 8, 0x16, 37 }, /* 0001 0110 */ - { 8, 0x17, 38 }, /* 0001 0111 */ - { 8, 0x28, 39 }, /* 0010 1000 */ - { 8, 0x29, 40 }, /* 0010 1001 */ - { 8, 0x2A, 41 }, /* 0010 1010 */ - { 8, 0x2B, 42 }, /* 0010 1011 */ - { 8, 0x2C, 43 }, /* 0010 1100 */ - { 8, 0x2D, 44 }, /* 0010 1101 */ - { 8, 0x4, 45 }, /* 0000 0100 */ - { 8, 0x5, 46 }, /* 0000 0101 */ - { 8, 0xA, 47 }, /* 0000 1010 */ - { 8, 0xB, 48 }, /* 0000 1011 */ - { 8, 0x52, 49 }, /* 0101 0010 */ - { 8, 0x53, 50 }, /* 0101 0011 */ - { 8, 0x54, 51 }, /* 0101 0100 */ - { 8, 0x55, 52 }, /* 0101 0101 */ - { 8, 0x24, 53 }, /* 0010 0100 */ - { 8, 0x25, 54 }, /* 0010 0101 */ - { 8, 0x58, 55 }, /* 0101 1000 */ - { 8, 0x59, 56 }, /* 0101 1001 */ - { 8, 0x5A, 57 }, /* 0101 1010 */ - { 8, 0x5B, 58 }, /* 0101 1011 */ - { 8, 0x4A, 59 }, /* 0100 1010 */ - { 8, 0x4B, 60 }, /* 0100 1011 */ - { 8, 0x32, 61 }, /* 0011 0010 */ - { 8, 0x33, 62 }, /* 0011 0011 */ - { 8, 0x34, 63 }, /* 0011 0100 */ - { 5, 0x1B, 64 }, /* 1101 1 */ - { 5, 0x12, 128 }, /* 1001 0 */ - { 6, 0x17, 192 }, /* 0101 11 */ - { 7, 0x37, 256 }, /* 0110 111 */ - { 8, 0x36, 320 }, /* 0011 0110 */ - { 8, 0x37, 384 }, /* 0011 0111 */ - { 8, 0x64, 448 }, /* 0110 0100 */ - { 8, 0x65, 512 }, /* 0110 0101 */ - { 8, 0x68, 576 }, /* 0110 1000 */ - { 8, 0x67, 640 }, /* 0110 0111 */ - { 9, 0xCC, 704 }, /* 0110 0110 0 */ - { 9, 0xCD, 768 }, /* 0110 0110 1 */ - { 9, 0xD2, 832 }, /* 0110 1001 0 */ - { 9, 0xD3, 896 }, /* 0110 1001 1 */ - { 9, 0xD4, 960 }, /* 0110 1010 0 */ - { 9, 0xD5, 1024 }, /* 0110 1010 1 */ - { 9, 0xD6, 1088 }, /* 0110 1011 0 */ - { 9, 0xD7, 1152 }, /* 0110 1011 1 */ - { 9, 0xD8, 1216 }, /* 0110 1100 0 */ - { 9, 0xD9, 1280 }, /* 0110 1100 1 */ - { 9, 0xDA, 1344 }, /* 0110 1101 0 */ - { 9, 0xDB, 1408 }, /* 0110 1101 1 */ - { 9, 0x98, 1472 }, /* 0100 1100 0 */ - { 9, 0x99, 1536 }, /* 0100 1100 1 */ - { 9, 0x9A, 1600 }, /* 0100 1101 0 */ - { 6, 0x18, 1664 }, /* 0110 00 */ - { 9, 0x9B, 1728 }, /* 0100 1101 1 */ - { 11, 0x8, 1792 }, /* 0000 0001 000 */ - { 11, 0xC, 1856 }, /* 0000 0001 100 */ - { 11, 0xD, 1920 }, /* 0000 0001 101 */ - { 12, 0x12, 1984 }, /* 0000 0001 0010 */ - { 12, 0x13, 2048 }, /* 0000 0001 0011 */ - { 12, 0x14, 2112 }, /* 0000 0001 0100 */ - { 12, 0x15, 2176 }, /* 0000 0001 0101 */ - { 12, 0x16, 2240 }, /* 0000 0001 0110 */ - { 12, 0x17, 2304 }, /* 0000 0001 0111 */ - { 12, 0x1C, 2368 }, /* 0000 0001 1100 */ - { 12, 0x1D, 2432 }, /* 0000 0001 1101 */ - { 12, 0x1E, 2496 }, /* 0000 0001 1110 */ - { 12, 0x1F, 2560 }, /* 0000 0001 1111 */ - { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */ - { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */ - { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */ - { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */ - { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */ + {8, 0x35, 0}, /* 0011 0101 */ + {6, 0x7, 1}, /* 0001 11 */ + {4, 0x7, 2}, /* 0111 */ + {4, 0x8, 3}, /* 1000 */ + {4, 0xB, 4}, /* 1011 */ + {4, 0xC, 5}, /* 1100 */ + {4, 0xE, 6}, /* 1110 */ + {4, 0xF, 7}, /* 1111 */ + {5, 0x13, 8}, /* 1001 1 */ + {5, 0x14, 9}, /* 1010 0 */ + {5, 0x7, 10}, /* 0011 1 */ + {5, 0x8, 11}, /* 0100 0 */ + {6, 0x8, 12}, /* 0010 00 */ + {6, 0x3, 13}, /* 0000 11 */ + {6, 0x34, 14}, /* 1101 00 */ + {6, 0x35, 15}, /* 1101 01 */ + {6, 0x2A, 16}, /* 1010 10 */ + {6, 0x2B, 17}, /* 1010 11 */ + {7, 0x27, 18}, /* 0100 111 */ + {7, 0xC, 19}, /* 0001 100 */ + {7, 0x8, 20}, /* 0001 000 */ + {7, 0x17, 21}, /* 0010 111 */ + {7, 0x3, 22}, /* 0000 011 */ + {7, 0x4, 23}, /* 0000 100 */ + {7, 0x28, 24}, /* 0101 000 */ + {7, 0x2B, 25}, /* 0101 011 */ + {7, 0x13, 26}, /* 0010 011 */ + {7, 0x24, 27}, /* 0100 100 */ + {7, 0x18, 28}, /* 0011 000 */ + {8, 0x2, 29}, /* 0000 0010 */ + {8, 0x3, 30}, /* 0000 0011 */ + {8, 0x1A, 31}, /* 0001 1010 */ + {8, 0x1B, 32}, /* 0001 1011 */ + {8, 0x12, 33}, /* 0001 0010 */ + {8, 0x13, 34}, /* 0001 0011 */ + {8, 0x14, 35}, /* 0001 0100 */ + {8, 0x15, 36}, /* 0001 0101 */ + {8, 0x16, 37}, /* 0001 0110 */ + {8, 0x17, 38}, /* 0001 0111 */ + {8, 0x28, 39}, /* 0010 1000 */ + {8, 0x29, 40}, /* 0010 1001 */ + {8, 0x2A, 41}, /* 0010 1010 */ + {8, 0x2B, 42}, /* 0010 1011 */ + {8, 0x2C, 43}, /* 0010 1100 */ + {8, 0x2D, 44}, /* 0010 1101 */ + {8, 0x4, 45}, /* 0000 0100 */ + {8, 0x5, 46}, /* 0000 0101 */ + {8, 0xA, 47}, /* 0000 1010 */ + {8, 0xB, 48}, /* 0000 1011 */ + {8, 0x52, 49}, /* 0101 0010 */ + {8, 0x53, 50}, /* 0101 0011 */ + {8, 0x54, 51}, /* 0101 0100 */ + {8, 0x55, 52}, /* 0101 0101 */ + {8, 0x24, 53}, /* 0010 0100 */ + {8, 0x25, 54}, /* 0010 0101 */ + {8, 0x58, 55}, /* 0101 1000 */ + {8, 0x59, 56}, /* 0101 1001 */ + {8, 0x5A, 57}, /* 0101 1010 */ + {8, 0x5B, 58}, /* 0101 1011 */ + {8, 0x4A, 59}, /* 0100 1010 */ + {8, 0x4B, 60}, /* 0100 1011 */ + {8, 0x32, 61}, /* 0011 0010 */ + {8, 0x33, 62}, /* 0011 0011 */ + {8, 0x34, 63}, /* 0011 0100 */ + {5, 0x1B, 64}, /* 1101 1 */ + {5, 0x12, 128}, /* 1001 0 */ + {6, 0x17, 192}, /* 0101 11 */ + {7, 0x37, 256}, /* 0110 111 */ + {8, 0x36, 320}, /* 0011 0110 */ + {8, 0x37, 384}, /* 0011 0111 */ + {8, 0x64, 448}, /* 0110 0100 */ + {8, 0x65, 512}, /* 0110 0101 */ + {8, 0x68, 576}, /* 0110 1000 */ + {8, 0x67, 640}, /* 0110 0111 */ + {9, 0xCC, 704}, /* 0110 0110 0 */ + {9, 0xCD, 768}, /* 0110 0110 1 */ + {9, 0xD2, 832}, /* 0110 1001 0 */ + {9, 0xD3, 896}, /* 0110 1001 1 */ + {9, 0xD4, 960}, /* 0110 1010 0 */ + {9, 0xD5, 1024}, /* 0110 1010 1 */ + {9, 0xD6, 1088}, /* 0110 1011 0 */ + {9, 0xD7, 1152}, /* 0110 1011 1 */ + {9, 0xD8, 1216}, /* 0110 1100 0 */ + {9, 0xD9, 1280}, /* 0110 1100 1 */ + {9, 0xDA, 1344}, /* 0110 1101 0 */ + {9, 0xDB, 1408}, /* 0110 1101 1 */ + {9, 0x98, 1472}, /* 0100 1100 0 */ + {9, 0x99, 1536}, /* 0100 1100 1 */ + {9, 0x9A, 1600}, /* 0100 1101 0 */ + {6, 0x18, 1664}, /* 0110 00 */ + {9, 0x9B, 1728}, /* 0100 1101 1 */ + {11, 0x8, 1792}, /* 0000 0001 000 */ + {11, 0xC, 1856}, /* 0000 0001 100 */ + {11, 0xD, 1920}, /* 0000 0001 101 */ + {12, 0x12, 1984}, /* 0000 0001 0010 */ + {12, 0x13, 2048}, /* 0000 0001 0011 */ + {12, 0x14, 2112}, /* 0000 0001 0100 */ + {12, 0x15, 2176}, /* 0000 0001 0101 */ + {12, 0x16, 2240}, /* 0000 0001 0110 */ + {12, 0x17, 2304}, /* 0000 0001 0111 */ + {12, 0x1C, 2368}, /* 0000 0001 1100 */ + {12, 0x1D, 2432}, /* 0000 0001 1101 */ + {12, 0x1E, 2496}, /* 0000 0001 1110 */ + {12, 0x1F, 2560}, /* 0000 0001 1111 */ + {12, 0x1, G3CODE_EOL}, /* 0000 0000 0001 */ + {9, 0x1, G3CODE_INVALID}, /* 0000 0000 1 */ + {10, 0x1, G3CODE_INVALID}, /* 0000 0000 01 */ + {11, 0x1, G3CODE_INVALID}, /* 0000 0000 001 */ + {12, 0x0, G3CODE_INVALID}, /* 0000 0000 0000 */ }; const tableentry TIFFFaxBlackCodes[] = { - { 10, 0x37, 0 }, /* 0000 1101 11 */ - { 3, 0x2, 1 }, /* 010 */ - { 2, 0x3, 2 }, /* 11 */ - { 2, 0x2, 3 }, /* 10 */ - { 3, 0x3, 4 }, /* 011 */ - { 4, 0x3, 5 }, /* 0011 */ - { 4, 0x2, 6 }, /* 0010 */ - { 5, 0x3, 7 }, /* 0001 1 */ - { 6, 0x5, 8 }, /* 0001 01 */ - { 6, 0x4, 9 }, /* 0001 00 */ - { 7, 0x4, 10 }, /* 0000 100 */ - { 7, 0x5, 11 }, /* 0000 101 */ - { 7, 0x7, 12 }, /* 0000 111 */ - { 8, 0x4, 13 }, /* 0000 0100 */ - { 8, 0x7, 14 }, /* 0000 0111 */ - { 9, 0x18, 15 }, /* 0000 1100 0 */ - { 10, 0x17, 16 }, /* 0000 0101 11 */ - { 10, 0x18, 17 }, /* 0000 0110 00 */ - { 10, 0x8, 18 }, /* 0000 0010 00 */ - { 11, 0x67, 19 }, /* 0000 1100 111 */ - { 11, 0x68, 20 }, /* 0000 1101 000 */ - { 11, 0x6C, 21 }, /* 0000 1101 100 */ - { 11, 0x37, 22 }, /* 0000 0110 111 */ - { 11, 0x28, 23 }, /* 0000 0101 000 */ - { 11, 0x17, 24 }, /* 0000 0010 111 */ - { 11, 0x18, 25 }, /* 0000 0011 000 */ - { 12, 0xCA, 26 }, /* 0000 1100 1010 */ - { 12, 0xCB, 27 }, /* 0000 1100 1011 */ - { 12, 0xCC, 28 }, /* 0000 1100 1100 */ - { 12, 0xCD, 29 }, /* 0000 1100 1101 */ - { 12, 0x68, 30 }, /* 0000 0110 1000 */ - { 12, 0x69, 31 }, /* 0000 0110 1001 */ - { 12, 0x6A, 32 }, /* 0000 0110 1010 */ - { 12, 0x6B, 33 }, /* 0000 0110 1011 */ - { 12, 0xD2, 34 }, /* 0000 1101 0010 */ - { 12, 0xD3, 35 }, /* 0000 1101 0011 */ - { 12, 0xD4, 36 }, /* 0000 1101 0100 */ - { 12, 0xD5, 37 }, /* 0000 1101 0101 */ - { 12, 0xD6, 38 }, /* 0000 1101 0110 */ - { 12, 0xD7, 39 }, /* 0000 1101 0111 */ - { 12, 0x6C, 40 }, /* 0000 0110 1100 */ - { 12, 0x6D, 41 }, /* 0000 0110 1101 */ - { 12, 0xDA, 42 }, /* 0000 1101 1010 */ - { 12, 0xDB, 43 }, /* 0000 1101 1011 */ - { 12, 0x54, 44 }, /* 0000 0101 0100 */ - { 12, 0x55, 45 }, /* 0000 0101 0101 */ - { 12, 0x56, 46 }, /* 0000 0101 0110 */ - { 12, 0x57, 47 }, /* 0000 0101 0111 */ - { 12, 0x64, 48 }, /* 0000 0110 0100 */ - { 12, 0x65, 49 }, /* 0000 0110 0101 */ - { 12, 0x52, 50 }, /* 0000 0101 0010 */ - { 12, 0x53, 51 }, /* 0000 0101 0011 */ - { 12, 0x24, 52 }, /* 0000 0010 0100 */ - { 12, 0x37, 53 }, /* 0000 0011 0111 */ - { 12, 0x38, 54 }, /* 0000 0011 1000 */ - { 12, 0x27, 55 }, /* 0000 0010 0111 */ - { 12, 0x28, 56 }, /* 0000 0010 1000 */ - { 12, 0x58, 57 }, /* 0000 0101 1000 */ - { 12, 0x59, 58 }, /* 0000 0101 1001 */ - { 12, 0x2B, 59 }, /* 0000 0010 1011 */ - { 12, 0x2C, 60 }, /* 0000 0010 1100 */ - { 12, 0x5A, 61 }, /* 0000 0101 1010 */ - { 12, 0x66, 62 }, /* 0000 0110 0110 */ - { 12, 0x67, 63 }, /* 0000 0110 0111 */ - { 10, 0xF, 64 }, /* 0000 0011 11 */ - { 12, 0xC8, 128 }, /* 0000 1100 1000 */ - { 12, 0xC9, 192 }, /* 0000 1100 1001 */ - { 12, 0x5B, 256 }, /* 0000 0101 1011 */ - { 12, 0x33, 320 }, /* 0000 0011 0011 */ - { 12, 0x34, 384 }, /* 0000 0011 0100 */ - { 12, 0x35, 448 }, /* 0000 0011 0101 */ - { 13, 0x6C, 512 }, /* 0000 0011 0110 0 */ - { 13, 0x6D, 576 }, /* 0000 0011 0110 1 */ - { 13, 0x4A, 640 }, /* 0000 0010 0101 0 */ - { 13, 0x4B, 704 }, /* 0000 0010 0101 1 */ - { 13, 0x4C, 768 }, /* 0000 0010 0110 0 */ - { 13, 0x4D, 832 }, /* 0000 0010 0110 1 */ - { 13, 0x72, 896 }, /* 0000 0011 1001 0 */ - { 13, 0x73, 960 }, /* 0000 0011 1001 1 */ - { 13, 0x74, 1024 }, /* 0000 0011 1010 0 */ - { 13, 0x75, 1088 }, /* 0000 0011 1010 1 */ - { 13, 0x76, 1152 }, /* 0000 0011 1011 0 */ - { 13, 0x77, 1216 }, /* 0000 0011 1011 1 */ - { 13, 0x52, 1280 }, /* 0000 0010 1001 0 */ - { 13, 0x53, 1344 }, /* 0000 0010 1001 1 */ - { 13, 0x54, 1408 }, /* 0000 0010 1010 0 */ - { 13, 0x55, 1472 }, /* 0000 0010 1010 1 */ - { 13, 0x5A, 1536 }, /* 0000 0010 1101 0 */ - { 13, 0x5B, 1600 }, /* 0000 0010 1101 1 */ - { 13, 0x64, 1664 }, /* 0000 0011 0010 0 */ - { 13, 0x65, 1728 }, /* 0000 0011 0010 1 */ - { 11, 0x8, 1792 }, /* 0000 0001 000 */ - { 11, 0xC, 1856 }, /* 0000 0001 100 */ - { 11, 0xD, 1920 }, /* 0000 0001 101 */ - { 12, 0x12, 1984 }, /* 0000 0001 0010 */ - { 12, 0x13, 2048 }, /* 0000 0001 0011 */ - { 12, 0x14, 2112 }, /* 0000 0001 0100 */ - { 12, 0x15, 2176 }, /* 0000 0001 0101 */ - { 12, 0x16, 2240 }, /* 0000 0001 0110 */ - { 12, 0x17, 2304 }, /* 0000 0001 0111 */ - { 12, 0x1C, 2368 }, /* 0000 0001 1100 */ - { 12, 0x1D, 2432 }, /* 0000 0001 1101 */ - { 12, 0x1E, 2496 }, /* 0000 0001 1110 */ - { 12, 0x1F, 2560 }, /* 0000 0001 1111 */ - { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */ - { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */ - { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */ - { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */ - { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */ + {10, 0x37, 0}, /* 0000 1101 11 */ + {3, 0x2, 1}, /* 010 */ + {2, 0x3, 2}, /* 11 */ + {2, 0x2, 3}, /* 10 */ + {3, 0x3, 4}, /* 011 */ + {4, 0x3, 5}, /* 0011 */ + {4, 0x2, 6}, /* 0010 */ + {5, 0x3, 7}, /* 0001 1 */ + {6, 0x5, 8}, /* 0001 01 */ + {6, 0x4, 9}, /* 0001 00 */ + {7, 0x4, 10}, /* 0000 100 */ + {7, 0x5, 11}, /* 0000 101 */ + {7, 0x7, 12}, /* 0000 111 */ + {8, 0x4, 13}, /* 0000 0100 */ + {8, 0x7, 14}, /* 0000 0111 */ + {9, 0x18, 15}, /* 0000 1100 0 */ + {10, 0x17, 16}, /* 0000 0101 11 */ + {10, 0x18, 17}, /* 0000 0110 00 */ + {10, 0x8, 18}, /* 0000 0010 00 */ + {11, 0x67, 19}, /* 0000 1100 111 */ + {11, 0x68, 20}, /* 0000 1101 000 */ + {11, 0x6C, 21}, /* 0000 1101 100 */ + {11, 0x37, 22}, /* 0000 0110 111 */ + {11, 0x28, 23}, /* 0000 0101 000 */ + {11, 0x17, 24}, /* 0000 0010 111 */ + {11, 0x18, 25}, /* 0000 0011 000 */ + {12, 0xCA, 26}, /* 0000 1100 1010 */ + {12, 0xCB, 27}, /* 0000 1100 1011 */ + {12, 0xCC, 28}, /* 0000 1100 1100 */ + {12, 0xCD, 29}, /* 0000 1100 1101 */ + {12, 0x68, 30}, /* 0000 0110 1000 */ + {12, 0x69, 31}, /* 0000 0110 1001 */ + {12, 0x6A, 32}, /* 0000 0110 1010 */ + {12, 0x6B, 33}, /* 0000 0110 1011 */ + {12, 0xD2, 34}, /* 0000 1101 0010 */ + {12, 0xD3, 35}, /* 0000 1101 0011 */ + {12, 0xD4, 36}, /* 0000 1101 0100 */ + {12, 0xD5, 37}, /* 0000 1101 0101 */ + {12, 0xD6, 38}, /* 0000 1101 0110 */ + {12, 0xD7, 39}, /* 0000 1101 0111 */ + {12, 0x6C, 40}, /* 0000 0110 1100 */ + {12, 0x6D, 41}, /* 0000 0110 1101 */ + {12, 0xDA, 42}, /* 0000 1101 1010 */ + {12, 0xDB, 43}, /* 0000 1101 1011 */ + {12, 0x54, 44}, /* 0000 0101 0100 */ + {12, 0x55, 45}, /* 0000 0101 0101 */ + {12, 0x56, 46}, /* 0000 0101 0110 */ + {12, 0x57, 47}, /* 0000 0101 0111 */ + {12, 0x64, 48}, /* 0000 0110 0100 */ + {12, 0x65, 49}, /* 0000 0110 0101 */ + {12, 0x52, 50}, /* 0000 0101 0010 */ + {12, 0x53, 51}, /* 0000 0101 0011 */ + {12, 0x24, 52}, /* 0000 0010 0100 */ + {12, 0x37, 53}, /* 0000 0011 0111 */ + {12, 0x38, 54}, /* 0000 0011 1000 */ + {12, 0x27, 55}, /* 0000 0010 0111 */ + {12, 0x28, 56}, /* 0000 0010 1000 */ + {12, 0x58, 57}, /* 0000 0101 1000 */ + {12, 0x59, 58}, /* 0000 0101 1001 */ + {12, 0x2B, 59}, /* 0000 0010 1011 */ + {12, 0x2C, 60}, /* 0000 0010 1100 */ + {12, 0x5A, 61}, /* 0000 0101 1010 */ + {12, 0x66, 62}, /* 0000 0110 0110 */ + {12, 0x67, 63}, /* 0000 0110 0111 */ + {10, 0xF, 64}, /* 0000 0011 11 */ + {12, 0xC8, 128}, /* 0000 1100 1000 */ + {12, 0xC9, 192}, /* 0000 1100 1001 */ + {12, 0x5B, 256}, /* 0000 0101 1011 */ + {12, 0x33, 320}, /* 0000 0011 0011 */ + {12, 0x34, 384}, /* 0000 0011 0100 */ + {12, 0x35, 448}, /* 0000 0011 0101 */ + {13, 0x6C, 512}, /* 0000 0011 0110 0 */ + {13, 0x6D, 576}, /* 0000 0011 0110 1 */ + {13, 0x4A, 640}, /* 0000 0010 0101 0 */ + {13, 0x4B, 704}, /* 0000 0010 0101 1 */ + {13, 0x4C, 768}, /* 0000 0010 0110 0 */ + {13, 0x4D, 832}, /* 0000 0010 0110 1 */ + {13, 0x72, 896}, /* 0000 0011 1001 0 */ + {13, 0x73, 960}, /* 0000 0011 1001 1 */ + {13, 0x74, 1024}, /* 0000 0011 1010 0 */ + {13, 0x75, 1088}, /* 0000 0011 1010 1 */ + {13, 0x76, 1152}, /* 0000 0011 1011 0 */ + {13, 0x77, 1216}, /* 0000 0011 1011 1 */ + {13, 0x52, 1280}, /* 0000 0010 1001 0 */ + {13, 0x53, 1344}, /* 0000 0010 1001 1 */ + {13, 0x54, 1408}, /* 0000 0010 1010 0 */ + {13, 0x55, 1472}, /* 0000 0010 1010 1 */ + {13, 0x5A, 1536}, /* 0000 0010 1101 0 */ + {13, 0x5B, 1600}, /* 0000 0010 1101 1 */ + {13, 0x64, 1664}, /* 0000 0011 0010 0 */ + {13, 0x65, 1728}, /* 0000 0011 0010 1 */ + {11, 0x8, 1792}, /* 0000 0001 000 */ + {11, 0xC, 1856}, /* 0000 0001 100 */ + {11, 0xD, 1920}, /* 0000 0001 101 */ + {12, 0x12, 1984}, /* 0000 0001 0010 */ + {12, 0x13, 2048}, /* 0000 0001 0011 */ + {12, 0x14, 2112}, /* 0000 0001 0100 */ + {12, 0x15, 2176}, /* 0000 0001 0101 */ + {12, 0x16, 2240}, /* 0000 0001 0110 */ + {12, 0x17, 2304}, /* 0000 0001 0111 */ + {12, 0x1C, 2368}, /* 0000 0001 1100 */ + {12, 0x1D, 2432}, /* 0000 0001 1101 */ + {12, 0x1E, 2496}, /* 0000 0001 1110 */ + {12, 0x1F, 2560}, /* 0000 0001 1111 */ + {12, 0x1, G3CODE_EOL}, /* 0000 0000 0001 */ + {9, 0x1, G3CODE_INVALID}, /* 0000 0000 1 */ + {10, 0x1, G3CODE_INVALID}, /* 0000 0000 01 */ + {11, 0x1, G3CODE_INVALID}, /* 0000 0000 001 */ + {12, 0x0, G3CODE_INVALID}, /* 0000 0000 0000 */ }; #else extern const tableentry TIFFFaxWhiteCodes[]; diff --git a/libtiff/tif_aux.c b/libtiff/tif_aux.c index 11d4b0b9..49855bb0 100644 --- a/libtiff/tif_aux.c +++ b/libtiff/tif_aux.c @@ -2,23 +2,23 @@ * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -27,173 +27,180 @@ * * Auxiliary Support Routines. */ -#include "tiffiop.h" #include "tif_predict.h" -#include <math.h> +#include "tiffiop.h" #include <float.h> +#include <math.h> -uint32_t -_TIFFMultiply32(TIFF* tif, uint32_t first, uint32_t second, const char* where) +uint32_t _TIFFMultiply32(TIFF *tif, uint32_t first, uint32_t second, + const char *where) { - if (second && first > UINT32_MAX / second) { - TIFFErrorExtR(tif, where, "Integer overflow in %s", where); - return 0; - } + if (second && first > UINT32_MAX / second) + { + TIFFErrorExtR(tif, where, "Integer overflow in %s", where); + return 0; + } - return first * second; + return first * second; } -uint64_t -_TIFFMultiply64(TIFF* tif, uint64_t first, uint64_t second, const char* where) +uint64_t _TIFFMultiply64(TIFF *tif, uint64_t first, uint64_t second, + const char *where) { - if (second && first > UINT64_MAX / second) { - TIFFErrorExtR(tif, where, "Integer overflow in %s", where); - return 0; - } + if (second && first > UINT64_MAX / second) + { + TIFFErrorExtR(tif, where, "Integer overflow in %s", where); + return 0; + } - return first * second; + return first * second; } -tmsize_t -_TIFFMultiplySSize(TIFF* tif, tmsize_t first, tmsize_t second, const char* where) +tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second, + const char *where) { - if( first <= 0 || second <= 0 ) + if (first <= 0 || second <= 0) { - if( tif != NULL && where != NULL ) + if (tif != NULL && where != NULL) { TIFFErrorExtR(tif, where, - "Invalid argument to _TIFFMultiplySSize() in %s", where); + "Invalid argument to _TIFFMultiplySSize() in %s", + where); } return 0; } - if( first > TIFF_TMSIZE_T_MAX / second ) + if (first > TIFF_TMSIZE_T_MAX / second) { - if( tif != NULL && where != NULL ) + if (tif != NULL && where != NULL) { - TIFFErrorExtR(tif, where, - "Integer overflow in %s", where); + TIFFErrorExtR(tif, where, "Integer overflow in %s", where); } return 0; } return first * second; } -tmsize_t _TIFFCastUInt64ToSSize(TIFF* tif, uint64_t val, const char* module) +tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module) { - if( val > (uint64_t)TIFF_TMSIZE_T_MAX ) + if (val > (uint64_t)TIFF_TMSIZE_T_MAX) { - if( tif != NULL && module != NULL ) + if (tif != NULL && module != NULL) { - TIFFErrorExtR(tif,module,"Integer overflow"); + TIFFErrorExtR(tif, module, "Integer overflow"); } return 0; } return (tmsize_t)val; } -void* -_TIFFCheckRealloc(TIFF* tif, void* buffer, - tmsize_t nmemb, tmsize_t elem_size, const char* what) +void *_TIFFCheckRealloc(TIFF *tif, void *buffer, tmsize_t nmemb, + tmsize_t elem_size, const char *what) { - void* cp = NULL; - tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL); - /* - * Check for integer overflow. - */ - if (count != 0) - { - cp = _TIFFreallocExt(tif, buffer, count); - } - - if (cp == NULL) { - TIFFErrorExtR(tif, tif->tif_name, - "Failed to allocate memory for %s " - "(%"TIFF_SSIZE_FORMAT" elements of %"TIFF_SSIZE_FORMAT" bytes each)", - what, nmemb, elem_size); - } - - return cp; + void *cp = NULL; + tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL); + /* + * Check for integer overflow. + */ + if (count != 0) + { + cp = _TIFFreallocExt(tif, buffer, count); + } + + if (cp == NULL) + { + TIFFErrorExtR(tif, tif->tif_name, + "Failed to allocate memory for %s " + "(%" TIFF_SSIZE_FORMAT " elements of %" TIFF_SSIZE_FORMAT + " bytes each)", + what, nmemb, elem_size); + } + + return cp; } -void* -_TIFFCheckMalloc(TIFF* tif, tmsize_t nmemb, tmsize_t elem_size, const char* what) +void *_TIFFCheckMalloc(TIFF *tif, tmsize_t nmemb, tmsize_t elem_size, + const char *what) { - return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what); + return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what); } -static int -TIFFDefaultTransferFunction(TIFF* tif, TIFFDirectory* td) +static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td) { - uint16_t **tf = td->td_transferfunction; - tmsize_t i, n, nbytes; - - tf[0] = tf[1] = tf[2] = 0; - if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2) - return 0; - - n = ((tmsize_t)1)<<td->td_bitspersample; - nbytes = n * sizeof (uint16_t); - tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes); - if (tf[0] == NULL) - return 0; - tf[0][0] = 0; - for (i = 1; i < n; i++) { - double t = (double)i/((double) n-1.); - tf[0][i] = (uint16_t)floor(65535. * pow(t, 2.2) + .5); - } - - if (td->td_samplesperpixel - td->td_extrasamples > 1) { - tf[1] = (uint16_t *)_TIFFmallocExt(tif, nbytes); - if(tf[1] == NULL) - goto bad; - _TIFFmemcpy(tf[1], tf[0], nbytes); - tf[2] = (uint16_t *)_TIFFmallocExt(tif, nbytes); - if (tf[2] == NULL) - goto bad; - _TIFFmemcpy(tf[2], tf[0], nbytes); - } - return 1; + uint16_t **tf = td->td_transferfunction; + tmsize_t i, n, nbytes; + + tf[0] = tf[1] = tf[2] = 0; + if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2) + return 0; + + n = ((tmsize_t)1) << td->td_bitspersample; + nbytes = n * sizeof(uint16_t); + tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes); + if (tf[0] == NULL) + return 0; + tf[0][0] = 0; + for (i = 1; i < n; i++) + { + double t = (double)i / ((double)n - 1.); + tf[0][i] = (uint16_t)floor(65535. * pow(t, 2.2) + .5); + } + + if (td->td_samplesperpixel - td->td_extrasamples > 1) + { + tf[1] = (uint16_t *)_TIFFmallocExt(tif, nbytes); + if (tf[1] == NULL) + goto bad; + _TIFFmemcpy(tf[1], tf[0], nbytes); + tf[2] = (uint16_t *)_TIFFmallocExt(tif, nbytes); + if (tf[2] == NULL) + goto bad; + _TIFFmemcpy(tf[2], tf[0], nbytes); + } + return 1; bad: - if (tf[0]) - _TIFFfreeExt(tif, tf[0]); - if (tf[1]) - _TIFFfreeExt(tif, tf[1]); - if (tf[2]) - _TIFFfreeExt(tif, tf[2]); - tf[0] = tf[1] = tf[2] = 0; - return 0; + if (tf[0]) + _TIFFfreeExt(tif, tf[0]); + if (tf[1]) + _TIFFfreeExt(tif, tf[1]); + if (tf[2]) + _TIFFfreeExt(tif, tf[2]); + tf[0] = tf[1] = tf[2] = 0; + return 0; } -static int -TIFFDefaultRefBlackWhite(TIFF* tif, TIFFDirectory* td) +static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td) { - int i; - - td->td_refblackwhite = (float *)_TIFFmallocExt(tif, 6*sizeof (float)); - if (td->td_refblackwhite == NULL) - return 0; - if (td->td_photometric == PHOTOMETRIC_YCBCR) { - /* - * YCbCr (Class Y) images must have the ReferenceBlackWhite - * tag set. Fix the broken images, which lacks that tag. - */ - td->td_refblackwhite[0] = 0.0F; - td->td_refblackwhite[1] = td->td_refblackwhite[3] = - td->td_refblackwhite[5] = 255.0F; - td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F; - } else { - /* - * Assume RGB (Class R) - */ - for (i = 0; i < 3; i++) { - td->td_refblackwhite[2*i+0] = 0; - td->td_refblackwhite[2*i+1] = - (float)((1L<<td->td_bitspersample)-1L); - } - } - return 1; + int i; + + td->td_refblackwhite = (float *)_TIFFmallocExt(tif, 6 * sizeof(float)); + if (td->td_refblackwhite == NULL) + return 0; + if (td->td_photometric == PHOTOMETRIC_YCBCR) + { + /* + * YCbCr (Class Y) images must have the ReferenceBlackWhite + * tag set. Fix the broken images, which lacks that tag. + */ + td->td_refblackwhite[0] = 0.0F; + td->td_refblackwhite[1] = td->td_refblackwhite[3] = + td->td_refblackwhite[5] = 255.0F; + td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F; + } + else + { + /* + * Assume RGB (Class R) + */ + for (i = 0; i < 3; i++) + { + td->td_refblackwhite[2 * i + 0] = 0; + td->td_refblackwhite[2 * i + 1] = + (float)((1L << td->td_bitspersample) - 1L); + } + } + return 1; } /* @@ -204,229 +211,246 @@ TIFFDefaultRefBlackWhite(TIFF* tif, TIFFDirectory* td) * explicit values so that defaults exist only one * place in the library -- in TIFFDefaultDirectory. */ -int -TIFFVGetFieldDefaulted(TIFF* tif, uint32_t tag, va_list ap) +int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap) { - TIFFDirectory *td = &tif->tif_dir; - - if (TIFFVGetField(tif, tag, ap)) - return (1); - switch (tag) { - case TIFFTAG_SUBFILETYPE: - *va_arg(ap, uint32_t *) = td->td_subfiletype; - return (1); - case TIFFTAG_BITSPERSAMPLE: - *va_arg(ap, uint16_t *) = td->td_bitspersample; - return (1); - case TIFFTAG_THRESHHOLDING: - *va_arg(ap, uint16_t *) = td->td_threshholding; - return (1); - case TIFFTAG_FILLORDER: - *va_arg(ap, uint16_t *) = td->td_fillorder; - return (1); - case TIFFTAG_ORIENTATION: - *va_arg(ap, uint16_t *) = td->td_orientation; - return (1); - case TIFFTAG_SAMPLESPERPIXEL: - *va_arg(ap, uint16_t *) = td->td_samplesperpixel; - return (1); - case TIFFTAG_ROWSPERSTRIP: - *va_arg(ap, uint32_t *) = td->td_rowsperstrip; - return (1); - case TIFFTAG_MINSAMPLEVALUE: - *va_arg(ap, uint16_t *) = td->td_minsamplevalue; - return (1); - case TIFFTAG_MAXSAMPLEVALUE: - { - uint16_t maxsamplevalue; - /* td_bitspersample=1 is always set in TIFFDefaultDirectory(). - * Therefore, td_maxsamplevalue has to be re-calculated in TIFFGetFieldDefaulted(). */ - if (td->td_bitspersample > 0) { - /* This shift operation into a uint16_t limits the value to 65535 even if td_bitspersamle is > 16 */ - if (td->td_bitspersample <= 16) { - maxsamplevalue = (1 << td->td_bitspersample) - 1; /* 2**(BitsPerSample) - 1 */ - } else { - maxsamplevalue = 65535; - } - } else { - maxsamplevalue = 0; - } - *va_arg(ap, uint16_t *) = maxsamplevalue; - return (1); - } - case TIFFTAG_PLANARCONFIG: - *va_arg(ap, uint16_t *) = td->td_planarconfig; - return (1); - case TIFFTAG_RESOLUTIONUNIT: - *va_arg(ap, uint16_t *) = td->td_resolutionunit; - return (1); - case TIFFTAG_PREDICTOR: + TIFFDirectory *td = &tif->tif_dir; + + if (TIFFVGetField(tif, tag, ap)) + return (1); + switch (tag) { - TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data; - if( sp == NULL ) + case TIFFTAG_SUBFILETYPE: + *va_arg(ap, uint32_t *) = td->td_subfiletype; + return (1); + case TIFFTAG_BITSPERSAMPLE: + *va_arg(ap, uint16_t *) = td->td_bitspersample; + return (1); + case TIFFTAG_THRESHHOLDING: + *va_arg(ap, uint16_t *) = td->td_threshholding; + return (1); + case TIFFTAG_FILLORDER: + *va_arg(ap, uint16_t *) = td->td_fillorder; + return (1); + case TIFFTAG_ORIENTATION: + *va_arg(ap, uint16_t *) = td->td_orientation; + return (1); + case TIFFTAG_SAMPLESPERPIXEL: + *va_arg(ap, uint16_t *) = td->td_samplesperpixel; + return (1); + case TIFFTAG_ROWSPERSTRIP: + *va_arg(ap, uint32_t *) = td->td_rowsperstrip; + return (1); + case TIFFTAG_MINSAMPLEVALUE: + *va_arg(ap, uint16_t *) = td->td_minsamplevalue; + return (1); + case TIFFTAG_MAXSAMPLEVALUE: + { + uint16_t maxsamplevalue; + /* td_bitspersample=1 is always set in TIFFDefaultDirectory(). + * Therefore, td_maxsamplevalue has to be re-calculated in + * TIFFGetFieldDefaulted(). */ + if (td->td_bitspersample > 0) + { + /* This shift operation into a uint16_t limits the value to + * 65535 even if td_bitspersamle is > 16 */ + if (td->td_bitspersample <= 16) + { + maxsamplevalue = (1 << td->td_bitspersample) - + 1; /* 2**(BitsPerSample) - 1 */ + } + else + { + maxsamplevalue = 65535; + } + } + else + { + maxsamplevalue = 0; + } + *va_arg(ap, uint16_t *) = maxsamplevalue; + return (1); + } + case TIFFTAG_PLANARCONFIG: + *va_arg(ap, uint16_t *) = td->td_planarconfig; + return (1); + case TIFFTAG_RESOLUTIONUNIT: + *va_arg(ap, uint16_t *) = td->td_resolutionunit; + return (1); + case TIFFTAG_PREDICTOR: + { + TIFFPredictorState *sp = (TIFFPredictorState *)tif->tif_data; + if (sp == NULL) + { + TIFFErrorExtR( + tif, tif->tif_name, + "Cannot get \"Predictor\" tag as plugin is not configured"); + *va_arg(ap, uint16_t *) = 0; + return 0; + } + *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor; + return 1; + } + case TIFFTAG_DOTRANGE: + *va_arg(ap, uint16_t *) = 0; + *va_arg(ap, uint16_t *) = (1 << td->td_bitspersample) - 1; + return (1); + case TIFFTAG_INKSET: + *va_arg(ap, uint16_t *) = INKSET_CMYK; + return 1; + case TIFFTAG_NUMBEROFINKS: + *va_arg(ap, uint16_t *) = 4; + return (1); + case TIFFTAG_EXTRASAMPLES: + *va_arg(ap, uint16_t *) = td->td_extrasamples; + *va_arg(ap, const uint16_t **) = td->td_sampleinfo; + return (1); + case TIFFTAG_MATTEING: + *va_arg(ap, uint16_t *) = + (td->td_extrasamples == 1 && + td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); + return (1); + case TIFFTAG_TILEDEPTH: + *va_arg(ap, uint32_t *) = td->td_tiledepth; + return (1); + case TIFFTAG_DATATYPE: + *va_arg(ap, uint16_t *) = td->td_sampleformat - 1; + return (1); + case TIFFTAG_SAMPLEFORMAT: + *va_arg(ap, uint16_t *) = td->td_sampleformat; + return (1); + case TIFFTAG_IMAGEDEPTH: + *va_arg(ap, uint32_t *) = td->td_imagedepth; + return (1); + case TIFFTAG_YCBCRCOEFFICIENTS: { - TIFFErrorExtR(tif, tif->tif_name, - "Cannot get \"Predictor\" tag as plugin is not configured"); - *va_arg(ap, uint16_t*) = 0; - return 0; + /* defaults are from CCIR Recommendation 601-1 */ + static const float ycbcrcoeffs[] = {0.299f, 0.587f, 0.114f}; + *va_arg(ap, const float **) = ycbcrcoeffs; + return 1; } - *va_arg(ap, uint16_t*) = (uint16_t) sp->predictor; - return 1; + case TIFFTAG_YCBCRSUBSAMPLING: + *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0]; + *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1]; + return (1); + case TIFFTAG_YCBCRPOSITIONING: + *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning; + return (1); + case TIFFTAG_WHITEPOINT: + { + /* TIFF 6.0 specification tells that it is no default + value for the WhitePoint, but AdobePhotoshop TIFF + Technical Note tells that it should be CIE D50. */ + static const float whitepoint[] = { + D50_X0 / (D50_X0 + D50_Y0 + D50_Z0), + D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0)}; + *va_arg(ap, const float **) = whitepoint; + return 1; + } + case TIFFTAG_TRANSFERFUNCTION: + if (!td->td_transferfunction[0] && + !TIFFDefaultTransferFunction(tif, td)) + { + TIFFErrorExtR(tif, tif->tif_name, + "No space for \"TransferFunction\" tag"); + return (0); + } + *va_arg(ap, const uint16_t **) = td->td_transferfunction[0]; + if (td->td_samplesperpixel - td->td_extrasamples > 1) + { + *va_arg(ap, const uint16_t **) = td->td_transferfunction[1]; + *va_arg(ap, const uint16_t **) = td->td_transferfunction[2]; + } + return (1); + case TIFFTAG_REFERENCEBLACKWHITE: + if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(tif, td)) + return (0); + *va_arg(ap, const float **) = td->td_refblackwhite; + return (1); } - case TIFFTAG_DOTRANGE: - *va_arg(ap, uint16_t *) = 0; - *va_arg(ap, uint16_t *) = (1 << td->td_bitspersample) - 1; - return (1); - case TIFFTAG_INKSET: - *va_arg(ap, uint16_t *) = INKSET_CMYK; - return 1; - case TIFFTAG_NUMBEROFINKS: - *va_arg(ap, uint16_t *) = 4; - return (1); - case TIFFTAG_EXTRASAMPLES: - *va_arg(ap, uint16_t *) = td->td_extrasamples; - *va_arg(ap, const uint16_t **) = td->td_sampleinfo; - return (1); - case TIFFTAG_MATTEING: - *va_arg(ap, uint16_t *) = - (td->td_extrasamples == 1 && - td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); - return (1); - case TIFFTAG_TILEDEPTH: - *va_arg(ap, uint32_t *) = td->td_tiledepth; - return (1); - case TIFFTAG_DATATYPE: - *va_arg(ap, uint16_t *) = td->td_sampleformat - 1; - return (1); - case TIFFTAG_SAMPLEFORMAT: - *va_arg(ap, uint16_t *) = td->td_sampleformat; - return(1); - case TIFFTAG_IMAGEDEPTH: - *va_arg(ap, uint32_t *) = td->td_imagedepth; - return (1); - case TIFFTAG_YCBCRCOEFFICIENTS: - { - /* defaults are from CCIR Recommendation 601-1 */ - static const float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f }; - *va_arg(ap, const float **) = ycbcrcoeffs; - return 1; - } - case TIFFTAG_YCBCRSUBSAMPLING: - *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0]; - *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1]; - return (1); - case TIFFTAG_YCBCRPOSITIONING: - *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning; - return (1); - case TIFFTAG_WHITEPOINT: - { - /* TIFF 6.0 specification tells that it is no default - value for the WhitePoint, but AdobePhotoshop TIFF - Technical Note tells that it should be CIE D50. */ - static const float whitepoint[] = { - D50_X0 / (D50_X0 + D50_Y0 + D50_Z0), - D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0) - }; - *va_arg(ap, const float **) = whitepoint; - return 1; - } - case TIFFTAG_TRANSFERFUNCTION: - if (!td->td_transferfunction[0] && - !TIFFDefaultTransferFunction(tif, td)) { - TIFFErrorExtR(tif, tif->tif_name, "No space for \"TransferFunction\" tag"); - return (0); - } - *va_arg(ap, const uint16_t **) = td->td_transferfunction[0]; - if (td->td_samplesperpixel - td->td_extrasamples > 1) { - *va_arg(ap, const uint16_t **) = td->td_transferfunction[1]; - *va_arg(ap, const uint16_t **) = td->td_transferfunction[2]; - } - return (1); - case TIFFTAG_REFERENCEBLACKWHITE: - if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(tif, td)) - return (0); - *va_arg(ap, const float **) = td->td_refblackwhite; - return (1); - } - return 0; + return 0; } /* * Like TIFFGetField, but return any default * value if the tag is not present in the directory. */ -int -TIFFGetFieldDefaulted(TIFF* tif, uint32_t tag, ...) +int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...) { - int ok; - va_list ap; + int ok; + va_list ap; - va_start(ap, tag); - ok = TIFFVGetFieldDefaulted(tif, tag, ap); - va_end(ap); - return (ok); + va_start(ap, tag); + ok = TIFFVGetFieldDefaulted(tif, tag, ap); + va_end(ap); + return (ok); } -struct _Int64Parts { - int32_t low, high; +struct _Int64Parts +{ + int32_t low, high; }; -typedef union { - struct _Int64Parts part; - int64_t value; +typedef union +{ + struct _Int64Parts part; + int64_t value; } _Int64; -float -_TIFFUInt64ToFloat(uint64_t ui64) +float _TIFFUInt64ToFloat(uint64_t ui64) { - _Int64 i; - - i.value = ui64; - if (i.part.high >= 0) { - return (float)i.value; - } else { - long double df; - df = (long double)i.value; - df += 18446744073709551616.0; /* adding 2**64 */ - return (float)df; - } + _Int64 i; + + i.value = ui64; + if (i.part.high >= 0) + { + return (float)i.value; + } + else + { + long double df; + df = (long double)i.value; + df += 18446744073709551616.0; /* adding 2**64 */ + return (float)df; + } } -double -_TIFFUInt64ToDouble(uint64_t ui64) +double _TIFFUInt64ToDouble(uint64_t ui64) { - _Int64 i; - - i.value = ui64; - if (i.part.high >= 0) { - return (double)i.value; - } else { - long double df; - df = (long double)i.value; - df += 18446744073709551616.0; /* adding 2**64 */ - return (double)df; - } + _Int64 i; + + i.value = ui64; + if (i.part.high >= 0) + { + return (double)i.value; + } + else + { + long double df; + df = (long double)i.value; + df += 18446744073709551616.0; /* adding 2**64 */ + return (double)df; + } } -float _TIFFClampDoubleToFloat( double val ) +float _TIFFClampDoubleToFloat(double val) { - if( val > FLT_MAX ) + if (val > FLT_MAX) return FLT_MAX; - if( val < -FLT_MAX ) + if (val < -FLT_MAX) return -FLT_MAX; return (float)val; } uint32_t _TIFFClampDoubleToUInt32(double val) { - if( val < 0 ) + if (val < 0) return 0; - if( val > 0xFFFFFFFFU || val != val ) + if (val > 0xFFFFFFFFU || val != val) return 0xFFFFFFFFU; return (uint32_t)val; } -int _TIFFSeekOK(TIFF* tif, toff_t off) +int _TIFFSeekOK(TIFF *tif, toff_t off) { /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */ /* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */ diff --git a/libtiff/tif_close.c b/libtiff/tif_close.c index 22bd3710..1dfe67ae 100644 --- a/libtiff/tif_close.c +++ b/libtiff/tif_close.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -37,77 +37,83 @@ * completely freed, so you should save opened file handle and pointer * to the close procedure in external variables before calling * _TIFFCleanup(), if you will need these ones to close the file. - * + * * @param tif A TIFF pointer. */ -void -TIFFCleanup(TIFF* tif) +void TIFFCleanup(TIFF *tif) { - /* - * Flush buffered data and directory (if dirty). - */ - if (tif->tif_mode != O_RDONLY) - TIFFFlush(tif); - (*tif->tif_cleanup)(tif); - TIFFFreeDirectory(tif); - - if (tif->tif_dirlistoff) - _TIFFfreeExt(tif, tif->tif_dirlistoff); - if (tif->tif_dirlistdirn) - _TIFFfreeExt(tif, tif->tif_dirlistdirn); - - /* - * Clean up client info links. - */ - while( tif->tif_clientinfo ) - { - TIFFClientInfoLink *psLink = tif->tif_clientinfo; - - tif->tif_clientinfo = psLink->next; - _TIFFfreeExt(tif, psLink->name ); - _TIFFfreeExt(tif, psLink ); - } - - if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER)) - _TIFFfreeExt(tif, tif->tif_rawdata); - if (isMapped(tif)) - TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size); - - /* - * Clean up custom fields. - */ - if (tif->tif_fields && tif->tif_nfields > 0) { - uint32_t i; - - for (i = 0; i < tif->tif_nfields; i++) { - TIFFField *fld = tif->tif_fields[i]; - if (fld->field_name != NULL) { - if (fld->field_bit == FIELD_CUSTOM && - /* caution: tif_fields[i] must not be the beginning of a fields-array. - * Otherwise the following tags are also freed with the first free(). - */ - TIFFFieldIsAnonymous(fld)) { - _TIFFfreeExt(tif, fld->field_name); - _TIFFfreeExt(tif, fld); - } - } - } - - _TIFFfreeExt(tif, tif->tif_fields); - } - - if (tif->tif_nfieldscompat > 0) { - uint32_t i; - - for (i = 0; i < tif->tif_nfieldscompat; i++) { - if (tif->tif_fieldscompat[i].allocated_size) - _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields); + /* + * Flush buffered data and directory (if dirty). + */ + if (tif->tif_mode != O_RDONLY) + TIFFFlush(tif); + (*tif->tif_cleanup)(tif); + TIFFFreeDirectory(tif); + + if (tif->tif_dirlistoff) + _TIFFfreeExt(tif, tif->tif_dirlistoff); + if (tif->tif_dirlistdirn) + _TIFFfreeExt(tif, tif->tif_dirlistdirn); + + /* + * Clean up client info links. + */ + while (tif->tif_clientinfo) + { + TIFFClientInfoLink *psLink = tif->tif_clientinfo; + + tif->tif_clientinfo = psLink->next; + _TIFFfreeExt(tif, psLink->name); + _TIFFfreeExt(tif, psLink); + } + + if (tif->tif_rawdata && (tif->tif_flags & TIFF_MYBUFFER)) + _TIFFfreeExt(tif, tif->tif_rawdata); + if (isMapped(tif)) + TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size); + + /* + * Clean up custom fields. + */ + if (tif->tif_fields && tif->tif_nfields > 0) + { + uint32_t i; + + for (i = 0; i < tif->tif_nfields; i++) + { + TIFFField *fld = tif->tif_fields[i]; + if (fld->field_name != NULL) + { + if (fld->field_bit == FIELD_CUSTOM && + /* caution: tif_fields[i] must not be the beginning of a + * fields-array. Otherwise the following tags are also freed + * with the first free(). + */ + TIFFFieldIsAnonymous(fld)) + { + _TIFFfreeExt(tif, fld->field_name); + _TIFFfreeExt(tif, fld); } - _TIFFfreeExt(tif, tif->tif_fieldscompat); + } + } + + _TIFFfreeExt(tif, tif->tif_fields); + } + + if (tif->tif_nfieldscompat > 0) + { + uint32_t i; + + for (i = 0; i < tif->tif_nfieldscompat; i++) + { + if (tif->tif_fieldscompat[i].allocated_size) + _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields); } + _TIFFfreeExt(tif, tif->tif_fieldscompat); + } - _TIFFfreeExt(NULL, tif); + _TIFFfreeExt(NULL, tif); } /************************************************************************/ @@ -120,16 +126,15 @@ TIFFCleanup(TIFF* tif) * TIFFClose closes a file that was previously opened with TIFFOpen(). * Any buffered data are flushed to the file, including the contents of * the current directory (if modified); and all resources are reclaimed. - * + * * @param tif A TIFF pointer. */ -void -TIFFClose(TIFF* tif) +void TIFFClose(TIFF *tif) { - TIFFCloseProc closeproc = tif->tif_closeproc; - thandle_t fd = tif->tif_clientdata; + TIFFCloseProc closeproc = tif->tif_closeproc; + thandle_t fd = tif->tif_clientdata; - TIFFCleanup(tif); - (void) (*closeproc)(fd); + TIFFCleanup(tif); + (void)(*closeproc)(fd); } diff --git a/libtiff/tif_codec.c b/libtiff/tif_codec.c index 9b3259ca..d499b63a 100644 --- a/libtiff/tif_codec.c +++ b/libtiff/tif_codec.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,7 +29,7 @@ */ #include "tiffiop.h" -static int NotConfigured(TIFF*, int); +static int NotConfigured(TIFF *, int); #ifndef LZW_SUPPORT #define TIFFInitLZW NotConfigured @@ -84,55 +84,52 @@ static int NotConfigured(TIFF*, int); * Compression schemes statically built into the library. */ const TIFFCodec _TIFFBuiltinCODECS[] = { - { "None", COMPRESSION_NONE, TIFFInitDumpMode }, - { "LZW", COMPRESSION_LZW, TIFFInitLZW }, - { "PackBits", COMPRESSION_PACKBITS, TIFFInitPackBits }, - { "ThunderScan", COMPRESSION_THUNDERSCAN,TIFFInitThunderScan }, - { "NeXT", COMPRESSION_NEXT, TIFFInitNeXT }, - { "JPEG", COMPRESSION_JPEG, TIFFInitJPEG }, - { "Old-style JPEG", COMPRESSION_OJPEG, TIFFInitOJPEG }, - { "CCITT RLE", COMPRESSION_CCITTRLE, TIFFInitCCITTRLE }, - { "CCITT RLE/W", COMPRESSION_CCITTRLEW, TIFFInitCCITTRLEW }, - { "CCITT Group 3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3 }, - { "CCITT Group 4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4 }, - { "ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG }, - { "Deflate", COMPRESSION_DEFLATE, TIFFInitZIP }, - { "AdobeDeflate", COMPRESSION_ADOBE_DEFLATE , TIFFInitZIP }, - { "PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog }, - { "SGILog", COMPRESSION_SGILOG, TIFFInitSGILog }, - { "SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog }, - { "LZMA", COMPRESSION_LZMA, TIFFInitLZMA }, - { "ZSTD", COMPRESSION_ZSTD, TIFFInitZSTD }, - { "WEBP", COMPRESSION_WEBP, TIFFInitWebP }, - { "LERC", COMPRESSION_LERC, TIFFInitLERC }, - { NULL, 0, NULL } -}; + {"None", COMPRESSION_NONE, TIFFInitDumpMode}, + {"LZW", COMPRESSION_LZW, TIFFInitLZW}, + {"PackBits", COMPRESSION_PACKBITS, TIFFInitPackBits}, + {"ThunderScan", COMPRESSION_THUNDERSCAN, TIFFInitThunderScan}, + {"NeXT", COMPRESSION_NEXT, TIFFInitNeXT}, + {"JPEG", COMPRESSION_JPEG, TIFFInitJPEG}, + {"Old-style JPEG", COMPRESSION_OJPEG, TIFFInitOJPEG}, + {"CCITT RLE", COMPRESSION_CCITTRLE, TIFFInitCCITTRLE}, + {"CCITT RLE/W", COMPRESSION_CCITTRLEW, TIFFInitCCITTRLEW}, + {"CCITT Group 3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3}, + {"CCITT Group 4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4}, + {"ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG}, + {"Deflate", COMPRESSION_DEFLATE, TIFFInitZIP}, + {"AdobeDeflate", COMPRESSION_ADOBE_DEFLATE, TIFFInitZIP}, + {"PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog}, + {"SGILog", COMPRESSION_SGILOG, TIFFInitSGILog}, + {"SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog}, + {"LZMA", COMPRESSION_LZMA, TIFFInitLZMA}, + {"ZSTD", COMPRESSION_ZSTD, TIFFInitZSTD}, + {"WEBP", COMPRESSION_WEBP, TIFFInitWebP}, + {"LERC", COMPRESSION_LERC, TIFFInitLERC}, + {NULL, 0, NULL}}; -static int -_notConfigured(TIFF* tif) +static int _notConfigured(TIFF *tif) { - const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); - char compression_code[20]; - - snprintf(compression_code, sizeof(compression_code), "%"PRIu16, - tif->tif_dir.td_compression ); - TIFFErrorExtR(tif, tif->tif_name, - "%s compression support is not configured", - c ? c->name : compression_code ); - return (0); + const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); + char compression_code[20]; + + snprintf(compression_code, sizeof(compression_code), "%" PRIu16, + tif->tif_dir.td_compression); + TIFFErrorExtR(tif, tif->tif_name, + "%s compression support is not configured", + c ? c->name : compression_code); + return (0); } -static int -NotConfigured(TIFF* tif, int scheme) +static int NotConfigured(TIFF *tif, int scheme) { - (void) scheme; + (void)scheme; - tif->tif_fixuptags = _notConfigured; - tif->tif_decodestatus = FALSE; - tif->tif_setupdecode = _notConfigured; - tif->tif_encodestatus = FALSE; - tif->tif_setupencode = _notConfigured; - return (1); + tif->tif_fixuptags = _notConfigured; + tif->tif_decodestatus = FALSE; + tif->tif_setupdecode = _notConfigured; + tif->tif_encodestatus = FALSE; + tif->tif_setupencode = _notConfigured; + return (1); } /************************************************************************/ @@ -146,19 +143,21 @@ NotConfigured(TIFF* tif, int scheme) * 0 will be returned. */ -int -TIFFIsCODECConfigured(uint16_t scheme) +int TIFFIsCODECConfigured(uint16_t scheme) { - const TIFFCodec* codec = TIFFFindCODEC(scheme); + const TIFFCodec *codec = TIFFFindCODEC(scheme); - if(codec == NULL) { - return 0; - } - if(codec->init == NULL) { - return 0; - } - if(codec->init != NotConfigured){ - return 1; - } - return 0; + if (codec == NULL) + { + return 0; + } + if (codec->init == NULL) + { + return 0; + } + if (codec->init != NotConfigured) + { + return 1; + } + return 0; } diff --git a/libtiff/tif_color.c b/libtiff/tif_color.c index 7fe2f1b1..2d7dcac6 100644 --- a/libtiff/tif_color.c +++ b/libtiff/tif_color.c @@ -40,11 +40,10 @@ /* * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ. */ -void -TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, - float *X, float *Y, float *Z) +void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, + float *X, float *Y, float *Z) { - TIFFCIELab16ToXYZ(cielab, l * 257, a * 256, b * 256, X, Y, Z); + TIFFCIELab16ToXYZ(cielab, l * 257, a * 256, b * 256, X, Y, Z); } /* @@ -53,78 +52,79 @@ TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, * bit chrominance values are encoded as 256 times the 1976 CIE a* and b* * values */ -void -TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, int32_t b, - float *X, float *Y, float *Z) +void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *cielab, uint32_t l, int32_t a, + int32_t b, float *X, float *Y, float *Z) { - float L = (float)l * 100.0F / 65535.0F; - float cby, tmp; - - if( L < 8.856F ) { - *Y = (L * cielab->Y0) / 903.292F; - cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F; - } else { - cby = (L + 16.0F) / 116.0F; - *Y = cielab->Y0 * cby * cby * cby; - } - - tmp = (float)a / 256.0F / 500.0F + cby; - if( tmp < 0.2069F ) - *X = cielab->X0 * (tmp - 0.13793F) / 7.787F; - else - *X = cielab->X0 * tmp * tmp * tmp; - - tmp = cby - (float)b / 256.0F / 200.0F; - if( tmp < 0.2069F ) - *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F; - else - *Z = cielab->Z0 * tmp * tmp * tmp; + float L = (float)l * 100.0F / 65535.0F; + float cby, tmp; + + if (L < 8.856F) + { + *Y = (L * cielab->Y0) / 903.292F; + cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F; + } + else + { + cby = (L + 16.0F) / 116.0F; + *Y = cielab->Y0 * cby * cby * cby; + } + + tmp = (float)a / 256.0F / 500.0F + cby; + if (tmp < 0.2069F) + *X = cielab->X0 * (tmp - 0.13793F) / 7.787F; + else + *X = cielab->X0 * tmp * tmp * tmp; + + tmp = cby - (float)b / 256.0F / 200.0F; + if (tmp < 0.2069F) + *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F; + else + *Z = cielab->Z0 * tmp * tmp * tmp; } -#define RINT(R) ((uint32_t)((R)>0?((R)+0.5):((R)-0.5))) +#define RINT(R) ((uint32_t)((R) > 0 ? ((R) + 0.5) : ((R)-0.5))) /* * Convert color value from the XYZ space to RGB. */ -void -TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, - uint32_t *r, uint32_t *g, uint32_t *b) +void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, + uint32_t *r, uint32_t *g, uint32_t *b) { - int i; - float Yr, Yg, Yb; - float *matrix = &cielab->display.d_mat[0][0]; - - /* Multiply through the matrix to get luminosity values. */ - Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z; - Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z; - Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z; - - /* Clip input */ - Yr = TIFFmax(Yr, cielab->display.d_Y0R); - Yg = TIFFmax(Yg, cielab->display.d_Y0G); - Yb = TIFFmax(Yb, cielab->display.d_Y0B); - - /* Avoid overflow in case of wrong input values */ - Yr = TIFFmin(Yr, cielab->display.d_YCR); - Yg = TIFFmin(Yg, cielab->display.d_YCG); - Yb = TIFFmin(Yb, cielab->display.d_YCB); - - /* Turn luminosity to colour value. */ - i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep); - i = TIFFmin(cielab->range, i); - *r = RINT(cielab->Yr2r[i]); - - i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep); - i = TIFFmin(cielab->range, i); - *g = RINT(cielab->Yg2g[i]); - - i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep); - i = TIFFmin(cielab->range, i); - *b = RINT(cielab->Yb2b[i]); - - /* Clip output. */ - *r = TIFFmin(*r, cielab->display.d_Vrwr); - *g = TIFFmin(*g, cielab->display.d_Vrwg); - *b = TIFFmin(*b, cielab->display.d_Vrwb); + int i; + float Yr, Yg, Yb; + float *matrix = &cielab->display.d_mat[0][0]; + + /* Multiply through the matrix to get luminosity values. */ + Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z; + Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z; + Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z; + + /* Clip input */ + Yr = TIFFmax(Yr, cielab->display.d_Y0R); + Yg = TIFFmax(Yg, cielab->display.d_Y0G); + Yb = TIFFmax(Yb, cielab->display.d_Y0B); + + /* Avoid overflow in case of wrong input values */ + Yr = TIFFmin(Yr, cielab->display.d_YCR); + Yg = TIFFmin(Yg, cielab->display.d_YCG); + Yb = TIFFmin(Yb, cielab->display.d_YCB); + + /* Turn luminosity to colour value. */ + i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep); + i = TIFFmin(cielab->range, i); + *r = RINT(cielab->Yr2r[i]); + + i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep); + i = TIFFmin(cielab->range, i); + *g = RINT(cielab->Yg2g[i]); + + i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep); + i = TIFFmin(cielab->range, i); + *b = RINT(cielab->Yb2b[i]); + + /* Clip output. */ + *r = TIFFmin(*r, cielab->display.d_Vrwr); + *g = TIFFmin(*g, cielab->display.d_Vrwg); + *b = TIFFmin(*b, cielab->display.d_Vrwb); } #undef RINT @@ -132,50 +132,52 @@ TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, * Allocate conversion state structures and make look_up tables for * the Yr,Yb,Yg <=> r,g,b conversions. */ -int -TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, - const TIFFDisplay *display, float *refWhite) +int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, + float *refWhite) { - int i; - double dfGamma; - - cielab->range = CIELABTORGB_TABLE_RANGE; - - _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay)); - - /* Red */ - dfGamma = 1.0 / cielab->display.d_gammaR ; - cielab->rstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for(i = 0; i <= cielab->range; i++) { - cielab->Yr2r[i] = cielab->display.d_Vrwr - * ((float)pow((double)i / cielab->range, dfGamma)); - } - - /* Green */ - dfGamma = 1.0 / cielab->display.d_gammaG ; - cielab->gstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for(i = 0; i <= cielab->range; i++) { - cielab->Yg2g[i] = cielab->display.d_Vrwg - * ((float)pow((double)i / cielab->range, dfGamma)); - } - - /* Blue */ - dfGamma = 1.0 / cielab->display.d_gammaB ; - cielab->bstep = - (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; - for(i = 0; i <= cielab->range; i++) { - cielab->Yb2b[i] = cielab->display.d_Vrwb - * ((float)pow((double)i / cielab->range, dfGamma)); - } - - /* Init reference white point */ - cielab->X0 = refWhite[0]; - cielab->Y0 = refWhite[1]; - cielab->Z0 = refWhite[2]; - - return 0; + int i; + double dfGamma; + + cielab->range = CIELABTORGB_TABLE_RANGE; + + _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay)); + + /* Red */ + dfGamma = 1.0 / cielab->display.d_gammaR; + cielab->rstep = + (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + for (i = 0; i <= cielab->range; i++) + { + cielab->Yr2r[i] = cielab->display.d_Vrwr * + ((float)pow((double)i / cielab->range, dfGamma)); + } + + /* Green */ + dfGamma = 1.0 / cielab->display.d_gammaG; + cielab->gstep = + (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + for (i = 0; i <= cielab->range; i++) + { + cielab->Yg2g[i] = cielab->display.d_Vrwg * + ((float)pow((double)i / cielab->range, dfGamma)); + } + + /* Blue */ + dfGamma = 1.0 / cielab->display.d_gammaB; + cielab->bstep = + (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range; + for (i = 0; i <= cielab->range; i++) + { + cielab->Yb2b[i] = cielab->display.d_Vrwb * + ((float)pow((double)i / cielab->range, dfGamma)); + } + + /* Init reference white point */ + cielab->X0 = refWhite[0]; + cielab->Y0 = refWhite[1]; + cielab->Z0 = refWhite[2]; + + return 0; } /* @@ -183,44 +185,46 @@ TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab, * The colorspace conversion algorithm comes from the IJG v5a code; * see below for more information on how it works. */ -#define SHIFT 16 -#define FIX(x) ((int32_t)((x) * (1L<<SHIFT) + 0.5)) -#define ONE_HALF ((int32_t)(1<<(SHIFT-1))) -#define Code2V(c, RB, RW, CR) ((((c)-(int32_t)(RB))*(float)(CR))/(float)(((RW)-(RB)!=0) ? ((RW)-(RB)) : 1)) +#define SHIFT 16 +#define FIX(x) ((int32_t)((x) * (1L << SHIFT) + 0.5)) +#define ONE_HALF ((int32_t)(1 << (SHIFT - 1))) +#define Code2V(c, RB, RW, CR) \ + ((((c) - (int32_t)(RB)) * (float)(CR)) / \ + (float)(((RW) - (RB) != 0) ? ((RW) - (RB)) : 1)) /* !((f)>=(min)) written that way to deal with NaN */ -#define CLAMP(f,min,max) ((!((f)>=(min)))?(min):(f)>(max)?(max):(f)) -#define HICLAMP(f,max) ((f)>(max)?(max):(f)) +#define CLAMP(f, min, max) \ + ((!((f) >= (min))) ? (min) : (f) > (max) ? (max) : (f)) +#define HICLAMP(f, max) ((f) > (max) ? (max) : (f)) -void -TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr, - uint32_t *r, uint32_t *g, uint32_t *b) +void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32_t Y, int32_t Cb, int32_t Cr, + uint32_t *r, uint32_t *g, uint32_t *b) { - int32_t i; - - /* XXX: Only 8-bit YCbCr input supported for now */ - Y = HICLAMP(Y, 255); - Cb = CLAMP(Cb, 0, 255); - Cr = CLAMP(Cr, 0, 255); - - i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]; - *r = CLAMP(i, 0, 255); - i = ycbcr->Y_tab[Y] - + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT); - *g = CLAMP(i, 0, 255); - i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]; - *b = CLAMP(i, 0, 255); + int32_t i; + + /* XXX: Only 8-bit YCbCr input supported for now */ + Y = HICLAMP(Y, 255); + Cb = CLAMP(Cb, 0, 255); + Cr = CLAMP(Cr, 0, 255); + + i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr]; + *r = CLAMP(i, 0, 255); + i = ycbcr->Y_tab[Y] + + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT); + *g = CLAMP(i, 0, 255); + i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb]; + *b = CLAMP(i, 0, 255); } /* Clamp function for sanitization purposes. Normally clamping should not */ /* occur for well behaved chroma and refBlackWhite coefficients */ static float CLAMPw(float v, float vmin, float vmax) { - if( v < vmin ) + if (v < vmin) { /* printf("%f clamped to %f\n", v, vmin); */ return vmin; } - if( v > vmax ) + if (v > vmax) { /* printf("%f clamped to %f\n", v, vmax); */ return vmax; @@ -244,69 +248,75 @@ static float CLAMPw(float v, float vmin, float vmax) * pre-calculating possible values indexed by Cb and Cr (this code * assumes conversion is being done for 8-bit samples). */ -int -TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite) +int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite) { - TIFFRGBValue* clamptab; + TIFFRGBValue *clamptab; int i; -#define LumaRed luma[0] -#define LumaGreen luma[1] -#define LumaBlue luma[2] +#define LumaRed luma[0] +#define LumaGreen luma[1] +#define LumaBlue luma[2] - clamptab = (TIFFRGBValue*)( - (uint8_t*) ycbcr + TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long))); - _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */ + clamptab = + (TIFFRGBValue *)((uint8_t *)ycbcr + + TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long))); + _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */ ycbcr->clamptab = (clamptab += 256); for (i = 0; i < 256; i++) - clamptab[i] = (TIFFRGBValue) i; - _TIFFmemset(clamptab+256, 255, 2*256); /* v > 255 => 255 */ - ycbcr->Cr_r_tab = (int*) (clamptab + 3*256); + clamptab[i] = (TIFFRGBValue)i; + _TIFFmemset(clamptab + 256, 255, 2 * 256); /* v > 255 => 255 */ + ycbcr->Cr_r_tab = (int *)(clamptab + 3 * 256); ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256; - ycbcr->Cr_g_tab = (int32_t*) (ycbcr->Cb_b_tab + 256); + ycbcr->Cr_g_tab = (int32_t *)(ycbcr->Cb_b_tab + 256); ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256; ycbcr->Y_tab = ycbcr->Cb_g_tab + 256; - { float f1 = 2-2*LumaRed; int32_t D1 = FIX(CLAMP(f1, 0.0F, 2.0F)); - float f2 = LumaRed*f1/LumaGreen; int32_t D2 = -FIX(CLAMP(f2, 0.0F, 2.0F)); - float f3 = 2-2*LumaBlue; int32_t D3 = FIX(CLAMP(f3, 0.0F, 2.0F)); - float f4 = LumaBlue*f3/LumaGreen; int32_t D4 = -FIX(CLAMP(f4, 0.0F, 2.0F)); - int x; + { + float f1 = 2 - 2 * LumaRed; + int32_t D1 = FIX(CLAMP(f1, 0.0F, 2.0F)); + float f2 = LumaRed * f1 / LumaGreen; + int32_t D2 = -FIX(CLAMP(f2, 0.0F, 2.0F)); + float f3 = 2 - 2 * LumaBlue; + int32_t D3 = FIX(CLAMP(f3, 0.0F, 2.0F)); + float f4 = LumaBlue * f3 / LumaGreen; + int32_t D4 = -FIX(CLAMP(f4, 0.0F, 2.0F)); + int x; #undef LumaBlue #undef LumaGreen #undef LumaRed - /* - * i is the actual input pixel value in the range 0..255 - * Cb and Cr values are in the range -128..127 (actually - * they are in a range defined by the ReferenceBlackWhite - * tag) so there is some range shifting to do here when - * constructing tables indexed by the raw pixel data. - */ - for (i = 0, x = -128; i < 256; i++, x++) { - int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F, - refBlackWhite[5] - 128.0F, 127), - -128.0F * 32, 128.0F * 32); - int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F, - refBlackWhite[3] - 128.0F, 127), - -128.0F * 32, 128.0F * 32); - - ycbcr->Cr_r_tab[i] = (int32_t)((D1 * Cr + ONE_HALF) >> SHIFT); - ycbcr->Cb_b_tab[i] = (int32_t)((D3 * Cb + ONE_HALF) >> SHIFT); - ycbcr->Cr_g_tab[i] = D2*Cr; - ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF; - ycbcr->Y_tab[i] = - (int32_t)CLAMPw(Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255), - -128.0F * 32, 128.0F * 32); - } + /* + * i is the actual input pixel value in the range 0..255 + * Cb and Cr values are in the range -128..127 (actually + * they are in a range defined by the ReferenceBlackWhite + * tag) so there is some range shifting to do here when + * constructing tables indexed by the raw pixel data. + */ + for (i = 0, x = -128; i < 256; i++, x++) + { + int32_t Cr = (int32_t)CLAMPw(Code2V(x, refBlackWhite[4] - 128.0F, + refBlackWhite[5] - 128.0F, 127), + -128.0F * 32, 128.0F * 32); + int32_t Cb = (int32_t)CLAMPw(Code2V(x, refBlackWhite[2] - 128.0F, + refBlackWhite[3] - 128.0F, 127), + -128.0F * 32, 128.0F * 32); + + ycbcr->Cr_r_tab[i] = (int32_t)((D1 * Cr + ONE_HALF) >> SHIFT); + ycbcr->Cb_b_tab[i] = (int32_t)((D3 * Cb + ONE_HALF) >> SHIFT); + ycbcr->Cr_g_tab[i] = D2 * Cr; + ycbcr->Cb_g_tab[i] = D4 * Cb + ONE_HALF; + ycbcr->Y_tab[i] = (int32_t)CLAMPw( + Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255), + -128.0F * 32, 128.0F * 32); + } } return 0; } -#undef HICLAMP -#undef CLAMP -#undef Code2V -#undef SHIFT -#undef ONE_HALF -#undef FIX +#undef HICLAMP +#undef CLAMP +#undef Code2V +#undef SHIFT +#undef ONE_HALF +#undef FIX diff --git a/libtiff/tif_compress.c b/libtiff/tif_compress.c index 7cf40096..c6e17d3e 100644 --- a/libtiff/tif_compress.c +++ b/libtiff/tif_compress.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,145 +29,152 @@ */ #include "tiffiop.h" -static int -TIFFNoEncode(TIFF* tif, const char* method) +static int TIFFNoEncode(TIFF *tif, const char *method) { - const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); - if (c) { - TIFFErrorExtR(tif, tif->tif_name, - "%s %s encoding is not implemented", - c->name, method); - } else { - TIFFErrorExtR(tif, tif->tif_name, - "Compression scheme %"PRIu16" %s encoding is not implemented", - tif->tif_dir.td_compression, method); - } - return (-1); + if (c) + { + TIFFErrorExtR(tif, tif->tif_name, "%s %s encoding is not implemented", + c->name, method); + } + else + { + TIFFErrorExtR(tif, tif->tif_name, + "Compression scheme %" PRIu16 + " %s encoding is not implemented", + tif->tif_dir.td_compression, method); + } + return (-1); } -int -_TIFFNoRowEncode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s) +int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoEncode(tif, "scanline")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoEncode(tif, "scanline")); } -int -_TIFFNoStripEncode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s) +int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoEncode(tif, "strip")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoEncode(tif, "strip")); } -int -_TIFFNoTileEncode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s) +int _TIFFNoTileEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoEncode(tif, "tile")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoEncode(tif, "tile")); } -static int -TIFFNoDecode(TIFF* tif, const char* method) +static int TIFFNoDecode(TIFF *tif, const char *method) { - const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); + const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); - if (c) - TIFFErrorExtR(tif, tif->tif_name, - "%s %s decoding is not implemented", - c->name, method); - else - TIFFErrorExtR(tif, tif->tif_name, - "Compression scheme %"PRIu16" %s decoding is not implemented", - tif->tif_dir.td_compression, method); - return (0); + if (c) + TIFFErrorExtR(tif, tif->tif_name, "%s %s decoding is not implemented", + c->name, method); + else + TIFFErrorExtR(tif, tif->tif_name, + "Compression scheme %" PRIu16 + " %s decoding is not implemented", + tif->tif_dir.td_compression, method); + return (0); } -static int -_TIFFNoFixupTags(TIFF* tif) +static int _TIFFNoFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } -int -_TIFFNoRowDecode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s) +int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoDecode(tif, "scanline")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoDecode(tif, "scanline")); } -int -_TIFFNoStripDecode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s) +int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoDecode(tif, "strip")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoDecode(tif, "strip")); } -int -_TIFFNoTileDecode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s) +int _TIFFNoTileDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) pp; (void) cc; (void) s; - return (TIFFNoDecode(tif, "tile")); + (void)pp; + (void)cc; + (void)s; + return (TIFFNoDecode(tif, "tile")); } -int -_TIFFNoSeek(TIFF* tif, uint32_t off) +int _TIFFNoSeek(TIFF *tif, uint32_t off) { - (void) off; - TIFFErrorExtR(tif, tif->tif_name, - "Compression algorithm does not support random access"); - return (0); + (void)off; + TIFFErrorExtR(tif, tif->tif_name, + "Compression algorithm does not support random access"); + return (0); } -int -_TIFFNoPreCode(TIFF* tif, uint16_t s) +int _TIFFNoPreCode(TIFF *tif, uint16_t s) { - (void) tif; (void) s; - return (1); + (void)tif; + (void)s; + return (1); } -static int _TIFFtrue(TIFF* tif) { (void) tif; return (1); } -static void _TIFFvoid(TIFF* tif) { (void) tif; } +static int _TIFFtrue(TIFF *tif) +{ + (void)tif; + return (1); +} +static void _TIFFvoid(TIFF *tif) { (void)tif; } -void -_TIFFSetDefaultCompressionState(TIFF* tif) +void _TIFFSetDefaultCompressionState(TIFF *tif) { - tif->tif_fixuptags = _TIFFNoFixupTags; - tif->tif_decodestatus = TRUE; - tif->tif_setupdecode = _TIFFtrue; - tif->tif_predecode = _TIFFNoPreCode; - tif->tif_decoderow = _TIFFNoRowDecode; - tif->tif_decodestrip = _TIFFNoStripDecode; - tif->tif_decodetile = _TIFFNoTileDecode; - tif->tif_encodestatus = TRUE; - tif->tif_setupencode = _TIFFtrue; - tif->tif_preencode = _TIFFNoPreCode; - tif->tif_postencode = _TIFFtrue; - tif->tif_encoderow = _TIFFNoRowEncode; - tif->tif_encodestrip = _TIFFNoStripEncode; - tif->tif_encodetile = _TIFFNoTileEncode; - tif->tif_close = _TIFFvoid; - tif->tif_seek = _TIFFNoSeek; - tif->tif_cleanup = _TIFFvoid; - tif->tif_defstripsize = _TIFFDefaultStripSize; - tif->tif_deftilesize = _TIFFDefaultTileSize; - tif->tif_flags &= ~(TIFF_NOBITREV|TIFF_NOREADRAW); + tif->tif_fixuptags = _TIFFNoFixupTags; + tif->tif_decodestatus = TRUE; + tif->tif_setupdecode = _TIFFtrue; + tif->tif_predecode = _TIFFNoPreCode; + tif->tif_decoderow = _TIFFNoRowDecode; + tif->tif_decodestrip = _TIFFNoStripDecode; + tif->tif_decodetile = _TIFFNoTileDecode; + tif->tif_encodestatus = TRUE; + tif->tif_setupencode = _TIFFtrue; + tif->tif_preencode = _TIFFNoPreCode; + tif->tif_postencode = _TIFFtrue; + tif->tif_encoderow = _TIFFNoRowEncode; + tif->tif_encodestrip = _TIFFNoStripEncode; + tif->tif_encodetile = _TIFFNoTileEncode; + tif->tif_close = _TIFFvoid; + tif->tif_seek = _TIFFNoSeek; + tif->tif_cleanup = _TIFFvoid; + tif->tif_defstripsize = _TIFFDefaultStripSize; + tif->tif_deftilesize = _TIFFDefaultTileSize; + tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW); } -int -TIFFSetCompressionScheme(TIFF* tif, int scheme) +int TIFFSetCompressionScheme(TIFF *tif, int scheme) { - const TIFFCodec *c = TIFFFindCODEC((uint16_t) scheme); + const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme); - _TIFFSetDefaultCompressionState(tif); - /* - * Don't treat an unknown compression scheme as an error. - * This permits applications to open files with data that - * the library does not have builtin support for, but which - * may still be meaningful. - */ - return (c ? (*c->init)(tif, scheme) : 1); + _TIFFSetDefaultCompressionState(tif); + /* + * Don't treat an unknown compression scheme as an error. + * This permits applications to open files with data that + * the library does not have builtin support for, but which + * may still be meaningful. + */ + return (c ? (*c->init)(tif, scheme) : 1); } /* @@ -175,64 +182,68 @@ TIFFSetCompressionScheme(TIFF* tif, int scheme) * schemes can also override the builtin versions provided * by this library. */ -typedef struct _codec { - struct _codec* next; - TIFFCodec* info; +typedef struct _codec +{ + struct _codec *next; + TIFFCodec *info; } codec_t; -static codec_t* registeredCODECS = NULL; +static codec_t *registeredCODECS = NULL; -const TIFFCodec* -TIFFFindCODEC(uint16_t scheme) +const TIFFCodec *TIFFFindCODEC(uint16_t scheme) { - const TIFFCodec* c; - codec_t* cd; + const TIFFCodec *c; + codec_t *cd; - for (cd = registeredCODECS; cd; cd = cd->next) - if (cd->info->scheme == scheme) - return ((const TIFFCodec*) cd->info); - for (c = _TIFFBuiltinCODECS; c->name; c++) - if (c->scheme == scheme) - return (c); - return ((const TIFFCodec*) 0); + for (cd = registeredCODECS; cd; cd = cd->next) + if (cd->info->scheme == scheme) + return ((const TIFFCodec *)cd->info); + for (c = _TIFFBuiltinCODECS; c->name; c++) + if (c->scheme == scheme) + return (c); + return ((const TIFFCodec *)0); } -TIFFCodec* -TIFFRegisterCODEC(uint16_t scheme, const char* name, TIFFInitMethod init) +TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name, + TIFFInitMethod init) { - codec_t* cd = (codec_t*) - _TIFFmallocExt(NULL, (tmsize_t)(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1)); + codec_t *cd = (codec_t *)_TIFFmallocExt( + NULL, + (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1)); - if (cd != NULL) { - cd->info = (TIFFCodec*) ((uint8_t*) cd + sizeof (codec_t)); - cd->info->name = (char*) - ((uint8_t*) cd->info + sizeof (TIFFCodec)); - strcpy(cd->info->name, name); - cd->info->scheme = scheme; - cd->info->init = init; - cd->next = registeredCODECS; - registeredCODECS = cd; - } else { - TIFFErrorExt(0, "TIFFRegisterCODEC", - "No space to register compression scheme %s", name); - return NULL; - } - return (cd->info); + if (cd != NULL) + { + cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t)); + cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec)); + strcpy(cd->info->name, name); + cd->info->scheme = scheme; + cd->info->init = init; + cd->next = registeredCODECS; + registeredCODECS = cd; + } + else + { + TIFFErrorExt(0, "TIFFRegisterCODEC", + "No space to register compression scheme %s", name); + return NULL; + } + return (cd->info); } -void -TIFFUnRegisterCODEC(TIFFCodec* c) +void TIFFUnRegisterCODEC(TIFFCodec *c) { - codec_t* cd; - codec_t** pcd; + codec_t *cd; + codec_t **pcd; - for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next) - if (cd->info == c) { - *pcd = cd->next; - _TIFFfreeExt(NULL, cd); - return; - } - TIFFErrorExt(0, "TIFFUnRegisterCODEC", - "Cannot remove compression scheme %s; not registered", c->name); + for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next) + if (cd->info == c) + { + *pcd = cd->next; + _TIFFfreeExt(NULL, cd); + return; + } + TIFFErrorExt(0, "TIFFUnRegisterCODEC", + "Cannot remove compression scheme %s; not registered", + c->name); } /************************************************************************/ @@ -242,52 +253,58 @@ TIFFUnRegisterCODEC(TIFFCodec* c) /** * Get list of configured codecs, both built-in and registered by user. * Caller is responsible to free this structure. - * + * * @return returns array of TIFFCodec records (the last record should be NULL) * or NULL if function failed. */ -TIFFCodec* -TIFFGetConfiguredCODECs() +TIFFCodec *TIFFGetConfiguredCODECs() { - int i = 1; - codec_t *cd; - const TIFFCodec* c; - TIFFCodec* codecs = NULL; - TIFFCodec* new_codecs; + int i = 1; + codec_t *cd; + const TIFFCodec *c; + TIFFCodec *codecs = NULL; + TIFFCodec *new_codecs; - for (cd = registeredCODECS; cd; cd = cd->next) { - new_codecs = (TIFFCodec *) - _TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); - if (!new_codecs) { - _TIFFfreeExt (NULL, codecs); - return NULL; - } - codecs = new_codecs; - _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec)); - i++; - } - for (c = _TIFFBuiltinCODECS; c->name; c++) { - if (TIFFIsCODECConfigured(c->scheme)) { - new_codecs = (TIFFCodec *) - _TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); - if (!new_codecs) { - _TIFFfreeExt (NULL, codecs); - return NULL; - } - codecs = new_codecs; - _TIFFmemcpy(codecs + i - 1, (const void*)c, sizeof(TIFFCodec)); - i++; - } - } + for (cd = registeredCODECS; cd; cd = cd->next) + { + new_codecs = + (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); + if (!new_codecs) + { + _TIFFfreeExt(NULL, codecs); + return NULL; + } + codecs = new_codecs; + _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec)); + i++; + } + for (c = _TIFFBuiltinCODECS; c->name; c++) + { + if (TIFFIsCODECConfigured(c->scheme)) + { + new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs, + i * sizeof(TIFFCodec)); + if (!new_codecs) + { + _TIFFfreeExt(NULL, codecs); + return NULL; + } + codecs = new_codecs; + _TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec)); + i++; + } + } - new_codecs = (TIFFCodec *) _TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); - if (!new_codecs) { - _TIFFfreeExt (NULL, codecs); - return NULL; - } - codecs = new_codecs; - _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec)); + new_codecs = + (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); + if (!new_codecs) + { + _TIFFfreeExt(NULL, codecs); + return NULL; + } + codecs = new_codecs; + _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec)); - return codecs; + return codecs; } diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c index 99a32184..6b58a2a3 100644 --- a/libtiff/tif_dir.c +++ b/libtiff/tif_dir.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,124 +29,157 @@ * (and also some miscellaneous stuff) */ #include "tiffiop.h" -#include <float.h> /*--: for Rational2Double */ +#include <float.h> /*--: for Rational2Double */ /* * These are used in the backwards compatibility code... */ -#define DATATYPE_VOID 0 /* !untyped data */ -#define DATATYPE_INT 1 /* !signed integer data */ -#define DATATYPE_UINT 2 /* !unsigned integer data */ -#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ +#define DATATYPE_VOID 0 /* !untyped data */ +#define DATATYPE_INT 1 /* !signed integer data */ +#define DATATYPE_UINT 2 /* !unsigned integer data */ +#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ + +static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb, + size_t elem_size) +{ + if (*vpp) + { + _TIFFfreeExt(tif, *vpp); + *vpp = 0; + } + if (vp) + { + tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL); + if (bytes) + *vpp = (void *)_TIFFmallocExt(tif, bytes); + if (*vpp) + _TIFFmemcpy(*vpp, vp, bytes); + } +} +void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n) +{ + setByteArray(NULL, vpp, vp, n, 1); +} +void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n) +{ + setByteArray(tif, vpp, vp, n, 1); +} + +static void _TIFFsetNString(TIFF *tif, char **cpp, const char *cp, uint32_t n) +{ + setByteArray(tif, (void **)cpp, cp, n, 1); +} + +void _TIFFsetShortArray(uint16_t **wpp, const uint16_t *wp, uint32_t n) +{ + setByteArray(NULL, (void **)wpp, wp, n, sizeof(uint16_t)); +} +void _TIFFsetShortArrayExt(TIFF *tif, uint16_t **wpp, const uint16_t *wp, + uint32_t n) +{ + setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t)); +} -static void -setByteArray(TIFF* tif, void** vpp, const void* vp, size_t nmemb, size_t elem_size) +void _TIFFsetLongArray(uint32_t **lpp, const uint32_t *lp, uint32_t n) { - if (*vpp) { - _TIFFfreeExt(tif, *vpp); - *vpp = 0; - } - if (vp) { - tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL); - if (bytes) - *vpp = (void*) _TIFFmallocExt(tif, bytes); - if (*vpp) - _TIFFmemcpy(*vpp, vp, bytes); - } + setByteArray(NULL, (void **)lpp, lp, n, sizeof(uint32_t)); } -void _TIFFsetByteArray(void** vpp, const void* vp, uint32_t n) - { setByteArray(NULL, vpp, vp, n, 1); } -void _TIFFsetByteArrayExt(TIFF* tif, void** vpp, const void* vp, uint32_t n) - { setByteArray(tif, vpp, vp, n, 1); } - -static void _TIFFsetNString(TIFF* tif, char** cpp, const char* cp, uint32_t n) - { setByteArray(tif, (void**) cpp, cp, n, 1); } - -void _TIFFsetShortArray(uint16_t** wpp, const uint16_t* wp, uint32_t n) - { setByteArray(NULL, (void**) wpp, wp, n, sizeof (uint16_t)); } -void _TIFFsetShortArrayExt(TIFF* tif, uint16_t** wpp, const uint16_t* wp, uint32_t n) - { setByteArray(tif, (void**) wpp, wp, n, sizeof (uint16_t)); } - -void _TIFFsetLongArray(uint32_t** lpp, const uint32_t* lp, uint32_t n) - { setByteArray(NULL, (void**) lpp, lp, n, sizeof (uint32_t)); } -void _TIFFsetLongArrayExt(TIFF* tif, uint32_t** lpp, const uint32_t* lp, uint32_t n) - { setByteArray(tif, (void**) lpp, lp, n, sizeof (uint32_t)); } - -static void _TIFFsetLong8Array(TIFF* tif, uint64_t** lpp, const uint64_t* lp, uint32_t n) - { setByteArray(tif, (void**) lpp, lp, n, sizeof (uint64_t)); } - -void _TIFFsetFloatArray(float** fpp, const float* fp, uint32_t n) - { setByteArray(NULL, (void**) fpp, fp, n, sizeof (float)); } -void _TIFFsetFloatArrayExt(TIFF* tif, float** fpp, const float* fp, uint32_t n) - { setByteArray(tif, (void**) fpp, fp, n, sizeof (float)); } - -void _TIFFsetDoubleArray(double** dpp, const double* dp, uint32_t n) - { setByteArray(NULL, (void**) dpp, dp, n, sizeof (double)); } -void _TIFFsetDoubleArrayExt(TIFF* tif, double** dpp, const double* dp, uint32_t n) - { setByteArray(tif, (void**) dpp, dp, n, sizeof (double)); } - -static void -setDoubleArrayOneValue(TIFF* tif, double** vpp, double value, size_t nmemb) +void _TIFFsetLongArrayExt(TIFF *tif, uint32_t **lpp, const uint32_t *lp, + uint32_t n) { - if (*vpp) - _TIFFfreeExt(tif, *vpp); - *vpp = _TIFFmallocExt(tif, nmemb*sizeof(double)); - if (*vpp) - { - while (nmemb--) - ((double*)*vpp)[nmemb] = value; - } + setByteArray(tif, (void **)lpp, lp, n, sizeof(uint32_t)); +} + +static void _TIFFsetLong8Array(TIFF *tif, uint64_t **lpp, const uint64_t *lp, + uint32_t n) +{ + setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t)); +} + +void _TIFFsetFloatArray(float **fpp, const float *fp, uint32_t n) +{ + setByteArray(NULL, (void **)fpp, fp, n, sizeof(float)); +} +void _TIFFsetFloatArrayExt(TIFF *tif, float **fpp, const float *fp, uint32_t n) +{ + setByteArray(tif, (void **)fpp, fp, n, sizeof(float)); +} + +void _TIFFsetDoubleArray(double **dpp, const double *dp, uint32_t n) +{ + setByteArray(NULL, (void **)dpp, dp, n, sizeof(double)); +} +void _TIFFsetDoubleArrayExt(TIFF *tif, double **dpp, const double *dp, + uint32_t n) +{ + setByteArray(tif, (void **)dpp, dp, n, sizeof(double)); +} + +static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value, + size_t nmemb) +{ + if (*vpp) + _TIFFfreeExt(tif, *vpp); + *vpp = _TIFFmallocExt(tif, nmemb * sizeof(double)); + if (*vpp) + { + while (nmemb--) + ((double *)*vpp)[nmemb] = value; + } } /* * Install extra samples information. */ -static int -setExtraSamples(TIFF* tif, va_list ap, uint32_t* v) +static int setExtraSamples(TIFF *tif, va_list ap, uint32_t *v) { /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */ -#define EXTRASAMPLE_COREL_UNASSALPHA 999 - - uint16_t* va; - uint32_t i; - TIFFDirectory* td = &tif->tif_dir; - static const char module[] = "setExtraSamples"; - - *v = (uint16_t) va_arg(ap, uint16_vap); - if ((uint16_t) *v > td->td_samplesperpixel) - return 0; - va = va_arg(ap, uint16_t*); - if (*v > 0 && va == NULL) /* typically missing param */ - return 0; - for (i = 0; i < *v; i++) { - if (va[i] > EXTRASAMPLE_UNASSALPHA) { - /* - * XXX: Corel Draw is known to produce incorrect - * ExtraSamples tags which must be patched here if we - * want to be able to open some of the damaged TIFF - * files: - */ - if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA) - va[i] = EXTRASAMPLE_UNASSALPHA; - else - return 0; - } - } - - if ( td->td_transferfunction[0] != NULL && (td->td_samplesperpixel - *v > 1) && - !(td->td_samplesperpixel - td->td_extrasamples > 1)) +#define EXTRASAMPLE_COREL_UNASSALPHA 999 + + uint16_t *va; + uint32_t i; + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "setExtraSamples"; + + *v = (uint16_t)va_arg(ap, uint16_vap); + if ((uint16_t)*v > td->td_samplesperpixel) + return 0; + va = va_arg(ap, uint16_t *); + if (*v > 0 && va == NULL) /* typically missing param */ + return 0; + for (i = 0; i < *v; i++) + { + if (va[i] > EXTRASAMPLE_UNASSALPHA) { - TIFFWarningExtR(tif,module, - "ExtraSamples tag value is changing, " - "but TransferFunction was read with a different value. Canceling it"); - TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION); - _TIFFfreeExt(tif, td->td_transferfunction[0]); - td->td_transferfunction[0] = NULL; + /* + * XXX: Corel Draw is known to produce incorrect + * ExtraSamples tags which must be patched here if we + * want to be able to open some of the damaged TIFF + * files: + */ + if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA) + va[i] = EXTRASAMPLE_UNASSALPHA; + else + return 0; } + } + + if (td->td_transferfunction[0] != NULL && + (td->td_samplesperpixel - *v > 1) && + !(td->td_samplesperpixel - td->td_extrasamples > 1)) + { + TIFFWarningExtR(tif, module, + "ExtraSamples tag value is changing, " + "but TransferFunction was read with a different value. " + "Canceling it"); + TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION); + _TIFFfreeExt(tif, td->td_transferfunction[0]); + td->td_transferfunction[0] = NULL; + } - td->td_extrasamples = (uint16_t) *v; - _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples); - return 1; + td->td_extrasamples = (uint16_t)*v; + _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples); + return 1; #undef EXTRASAMPLE_COREL_UNASSALPHA } @@ -155,781 +188,916 @@ setExtraSamples(TIFF* tif, va_list ap, uint32_t* v) * Count ink names separated by \0. Returns * zero if the ink names are not as expected. */ -static uint16_t -countInkNamesString(TIFF *tif, uint32_t slen, const char *s) +static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s) { - uint16_t i = 0; - const char *ep = s + slen; - const char *cp = s; - - if (slen > 0) { - do { - for (; cp < ep && *cp != '\0'; cp++) {} - if (cp >= ep) - goto bad; - cp++; /* skip \0 */ - i++; - } while (cp < ep); - return (i); - } + uint16_t i = 0; + const char *ep = s + slen; + const char *cp = s; + + if (slen > 0) + { + do + { + for (; cp < ep && *cp != '\0'; cp++) + { + } + if (cp >= ep) + goto bad; + cp++; /* skip \0 */ + i++; + } while (cp < ep); + return (i); + } bad: - TIFFErrorExtR(tif, "TIFFSetField", - "%s: Invalid InkNames value; no NUL at given buffer end location %"PRIu32", after %"PRIu16" ink", - tif->tif_name, slen, i); - return (0); + TIFFErrorExtR(tif, "TIFFSetField", + "%s: Invalid InkNames value; no NUL at given buffer end " + "location %" PRIu32 ", after %" PRIu16 " ink", + tif->tif_name, slen, i); + return (0); } -static int -_TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap) +static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[] = "_TIFFVSetField"; + static const char module[] = "_TIFFVSetField"; - TIFFDirectory* td = &tif->tif_dir; - int status = 1; - uint32_t v32, v; + TIFFDirectory *td = &tif->tif_dir; + int status = 1; + uint32_t v32, v; double dblval; - char* s; - const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); - uint32_t standard_tag = tag; - if( fip == NULL ) /* cannot happen since OkToChangeTag() already checks it */ - return 0; - /* - * We want to force the custom code to be used for custom - * fields even if the tag happens to match a well known - * one - important for reinterpreted handling of standard - * tag values in custom directories (i.e. EXIF) - */ - if (fip->field_bit == FIELD_CUSTOM) { - standard_tag = 0; - } - - switch (standard_tag) { - case TIFFTAG_SUBFILETYPE: - td->td_subfiletype = (uint32_t) va_arg(ap, uint32_t); - break; - case TIFFTAG_IMAGEWIDTH: - td->td_imagewidth = (uint32_t) va_arg(ap, uint32_t); - break; - case TIFFTAG_IMAGELENGTH: - td->td_imagelength = (uint32_t) va_arg(ap, uint32_t); - break; - case TIFFTAG_BITSPERSAMPLE: - td->td_bitspersample = (uint16_t) va_arg(ap, uint16_vap); - /* - * If the data require post-decoding processing to byte-swap - * samples, set it up here. Note that since tags are required - * to be ordered, compression code can override this behavior - * in the setup method if it wants to roll the post decoding - * work in with its normal work. - */ - if (tif->tif_flags & TIFF_SWAB) { - if (td->td_bitspersample == 8) - tif->tif_postdecode = _TIFFNoPostDecode; - else if (td->td_bitspersample == 16) - tif->tif_postdecode = _TIFFSwab16BitData; - else if (td->td_bitspersample == 24) - tif->tif_postdecode = _TIFFSwab24BitData; - else if (td->td_bitspersample == 32) - tif->tif_postdecode = _TIFFSwab32BitData; - else if (td->td_bitspersample == 64) - tif->tif_postdecode = _TIFFSwab64BitData; - else if (td->td_bitspersample == 128) /* two 64's */ - tif->tif_postdecode = _TIFFSwab64BitData; - } - break; - case TIFFTAG_COMPRESSION: - v = (uint16_t) va_arg(ap, uint16_vap); - /* - * If we're changing the compression scheme, notify the - * previous module so that it can cleanup any state it's - * setup. - */ - if (TIFFFieldSet(tif, FIELD_COMPRESSION)) { - if ((uint32_t)td->td_compression == v) - break; - (*tif->tif_cleanup)(tif); - tif->tif_flags &= ~TIFF_CODERSETUP; - } - /* - * Setup new compression routine state. - */ - if( (status = TIFFSetCompressionScheme(tif, v)) != 0 ) - td->td_compression = (uint16_t) v; - else - status = 0; - break; - case TIFFTAG_PHOTOMETRIC: - td->td_photometric = (uint16_t) va_arg(ap, uint16_vap); - break; - case TIFFTAG_THRESHHOLDING: - td->td_threshholding = (uint16_t) va_arg(ap, uint16_vap); - break; - case TIFFTAG_FILLORDER: - v = (uint16_t) va_arg(ap, uint16_vap); - if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) - goto badvalue; - td->td_fillorder = (uint16_t) v; - break; - case TIFFTAG_ORIENTATION: - v = (uint16_t) va_arg(ap, uint16_vap); - if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) - goto badvalue; - else - td->td_orientation = (uint16_t) v; - break; - case TIFFTAG_SAMPLESPERPIXEL: - v = (uint16_t) va_arg(ap, uint16_vap); - if (v == 0) - goto badvalue; - if( v != td->td_samplesperpixel ) - { - /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */ - if( td->td_sminsamplevalue != NULL ) + char *s; + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + uint32_t standard_tag = tag; + if (fip == NULL) /* cannot happen since OkToChangeTag() already checks it */ + return 0; + /* + * We want to force the custom code to be used for custom + * fields even if the tag happens to match a well known + * one - important for reinterpreted handling of standard + * tag values in custom directories (i.e. EXIF) + */ + if (fip->field_bit == FIELD_CUSTOM) + { + standard_tag = 0; + } + + switch (standard_tag) + { + case TIFFTAG_SUBFILETYPE: + td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_IMAGEWIDTH: + td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_IMAGELENGTH: + td->td_imagelength = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_BITSPERSAMPLE: + td->td_bitspersample = (uint16_t)va_arg(ap, uint16_vap); + /* + * If the data require post-decoding processing to byte-swap + * samples, set it up here. Note that since tags are required + * to be ordered, compression code can override this behavior + * in the setup method if it wants to roll the post decoding + * work in with its normal work. + */ + if (tif->tif_flags & TIFF_SWAB) { - TIFFWarningExtR(tif,module, - "SamplesPerPixel tag value is changing, " - "but SMinSampleValue tag was read with a different value. Canceling it"); - TIFFClrFieldBit(tif,FIELD_SMINSAMPLEVALUE); - _TIFFfreeExt(tif, td->td_sminsamplevalue); - td->td_sminsamplevalue = NULL; + if (td->td_bitspersample == 8) + tif->tif_postdecode = _TIFFNoPostDecode; + else if (td->td_bitspersample == 16) + tif->tif_postdecode = _TIFFSwab16BitData; + else if (td->td_bitspersample == 24) + tif->tif_postdecode = _TIFFSwab24BitData; + else if (td->td_bitspersample == 32) + tif->tif_postdecode = _TIFFSwab32BitData; + else if (td->td_bitspersample == 64) + tif->tif_postdecode = _TIFFSwab64BitData; + else if (td->td_bitspersample == 128) /* two 64's */ + tif->tif_postdecode = _TIFFSwab64BitData; } - if( td->td_smaxsamplevalue != NULL ) + break; + case TIFFTAG_COMPRESSION: + v = (uint16_t)va_arg(ap, uint16_vap); + /* + * If we're changing the compression scheme, notify the + * previous module so that it can cleanup any state it's + * setup. + */ + if (TIFFFieldSet(tif, FIELD_COMPRESSION)) { - TIFFWarningExtR(tif,module, - "SamplesPerPixel tag value is changing, " - "but SMaxSampleValue tag was read with a different value. Canceling it"); - TIFFClrFieldBit(tif,FIELD_SMAXSAMPLEVALUE); - _TIFFfreeExt(tif, td->td_smaxsamplevalue); - td->td_smaxsamplevalue = NULL; + if ((uint32_t)td->td_compression == v) + break; + (*tif->tif_cleanup)(tif); + tif->tif_flags &= ~TIFF_CODERSETUP; } - /* Test if 3 transfer functions instead of just one are now needed - See http://bugzilla.maptools.org/show_bug.cgi?id=2820 */ - if( td->td_transferfunction[0] != NULL && (v - td->td_extrasamples > 1) && - !(td->td_samplesperpixel - td->td_extrasamples > 1)) + /* + * Setup new compression routine state. + */ + if ((status = TIFFSetCompressionScheme(tif, v)) != 0) + td->td_compression = (uint16_t)v; + else + status = 0; + break; + case TIFFTAG_PHOTOMETRIC: + td->td_photometric = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_THRESHHOLDING: + td->td_threshholding = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_FILLORDER: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) + goto badvalue; + td->td_fillorder = (uint16_t)v; + break; + case TIFFTAG_ORIENTATION: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) + goto badvalue; + else + td->td_orientation = (uint16_t)v; + break; + case TIFFTAG_SAMPLESPERPIXEL: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v == 0) + goto badvalue; + if (v != td->td_samplesperpixel) { - TIFFWarningExtR(tif,module, - "SamplesPerPixel tag value is changing, " - "but TransferFunction was read with a different value. Canceling it"); - TIFFClrFieldBit(tif,FIELD_TRANSFERFUNCTION); + /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */ + if (td->td_sminsamplevalue != NULL) + { + TIFFWarningExtR(tif, module, + "SamplesPerPixel tag value is changing, " + "but SMinSampleValue tag was read with a " + "different value. Canceling it"); + TIFFClrFieldBit(tif, FIELD_SMINSAMPLEVALUE); + _TIFFfreeExt(tif, td->td_sminsamplevalue); + td->td_sminsamplevalue = NULL; + } + if (td->td_smaxsamplevalue != NULL) + { + TIFFWarningExtR(tif, module, + "SamplesPerPixel tag value is changing, " + "but SMaxSampleValue tag was read with a " + "different value. Canceling it"); + TIFFClrFieldBit(tif, FIELD_SMAXSAMPLEVALUE); + _TIFFfreeExt(tif, td->td_smaxsamplevalue); + td->td_smaxsamplevalue = NULL; + } + /* Test if 3 transfer functions instead of just one are now + needed See http://bugzilla.maptools.org/show_bug.cgi?id=2820 + */ + if (td->td_transferfunction[0] != NULL && + (v - td->td_extrasamples > 1) && + !(td->td_samplesperpixel - td->td_extrasamples > 1)) + { + TIFFWarningExtR(tif, module, + "SamplesPerPixel tag value is changing, " + "but TransferFunction was read with a " + "different value. Canceling it"); + TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION); _TIFFfreeExt(tif, td->td_transferfunction[0]); td->td_transferfunction[0] = NULL; + } + } + td->td_samplesperpixel = (uint16_t)v; + break; + case TIFFTAG_ROWSPERSTRIP: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 == 0) + goto badvalue32; + td->td_rowsperstrip = v32; + if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) + { + td->td_tilelength = v32; + td->td_tilewidth = td->td_imagewidth; + } + break; + case TIFFTAG_MINSAMPLEVALUE: + td->td_minsamplevalue = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_MAXSAMPLEVALUE: + td->td_maxsamplevalue = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_SMINSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue, + va_arg(ap, double *), + td->td_samplesperpixel); + else + setDoubleArrayOneValue(tif, &td->td_sminsamplevalue, + va_arg(ap, double), + td->td_samplesperpixel); + break; + case TIFFTAG_SMAXSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue, + va_arg(ap, double *), + td->td_samplesperpixel); + else + setDoubleArrayOneValue(tif, &td->td_smaxsamplevalue, + va_arg(ap, double), + td->td_samplesperpixel); + break; + case TIFFTAG_XRESOLUTION: + dblval = va_arg(ap, double); + if (dblval != dblval || dblval < 0) + goto badvaluedouble; + td->td_xresolution = _TIFFClampDoubleToFloat(dblval); + break; + case TIFFTAG_YRESOLUTION: + dblval = va_arg(ap, double); + if (dblval != dblval || dblval < 0) + goto badvaluedouble; + td->td_yresolution = _TIFFClampDoubleToFloat(dblval); + break; + case TIFFTAG_PLANARCONFIG: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) + goto badvalue; + td->td_planarconfig = (uint16_t)v; + break; + case TIFFTAG_XPOSITION: + td->td_xposition = _TIFFClampDoubleToFloat(va_arg(ap, double)); + break; + case TIFFTAG_YPOSITION: + td->td_yposition = _TIFFClampDoubleToFloat(va_arg(ap, double)); + break; + case TIFFTAG_RESOLUTIONUNIT: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) + goto badvalue; + td->td_resolutionunit = (uint16_t)v; + break; + case TIFFTAG_PAGENUMBER: + td->td_pagenumber[0] = (uint16_t)va_arg(ap, uint16_vap); + td->td_pagenumber[1] = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_HALFTONEHINTS: + td->td_halftonehints[0] = (uint16_t)va_arg(ap, uint16_vap); + td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_COLORMAP: + v32 = (uint32_t)(1L << td->td_bitspersample); + _TIFFsetShortArrayExt(tif, &td->td_colormap[0], + va_arg(ap, uint16_t *), v32); + _TIFFsetShortArrayExt(tif, &td->td_colormap[1], + va_arg(ap, uint16_t *), v32); + _TIFFsetShortArrayExt(tif, &td->td_colormap[2], + va_arg(ap, uint16_t *), v32); + break; + case TIFFTAG_EXTRASAMPLES: + if (!setExtraSamples(tif, ap, &v)) + goto badvalue; + break; + case TIFFTAG_MATTEING: + td->td_extrasamples = (((uint16_t)va_arg(ap, uint16_vap)) != 0); + if (td->td_extrasamples) + { + uint16_t sv = EXTRASAMPLE_ASSOCALPHA; + _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1); + } + break; + case TIFFTAG_TILEWIDTH: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 % 16) + { + if (tif->tif_mode != O_RDONLY) + goto badvalue32; + TIFFWarningExtR( + tif, tif->tif_name, + "Nonstandard tile width %" PRIu32 ", convert file", v32); + } + td->td_tilewidth = v32; + tif->tif_flags |= TIFF_ISTILED; + break; + case TIFFTAG_TILELENGTH: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 % 16) + { + if (tif->tif_mode != O_RDONLY) + goto badvalue32; + TIFFWarningExtR( + tif, tif->tif_name, + "Nonstandard tile length %" PRIu32 ", convert file", v32); + } + td->td_tilelength = v32; + tif->tif_flags |= TIFF_ISTILED; + break; + case TIFFTAG_TILEDEPTH: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 == 0) + goto badvalue32; + td->td_tiledepth = v32; + break; + case TIFFTAG_DATATYPE: + v = (uint16_t)va_arg(ap, uint16_vap); + switch (v) + { + case DATATYPE_VOID: + v = SAMPLEFORMAT_VOID; + break; + case DATATYPE_INT: + v = SAMPLEFORMAT_INT; + break; + case DATATYPE_UINT: + v = SAMPLEFORMAT_UINT; + break; + case DATATYPE_IEEEFP: + v = SAMPLEFORMAT_IEEEFP; + break; + default: + goto badvalue; + } + td->td_sampleformat = (uint16_t)v; + break; + case TIFFTAG_SAMPLEFORMAT: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) + goto badvalue; + td->td_sampleformat = (uint16_t)v; + + /* Try to fix up the SWAB function for complex data. */ + if (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT && + td->td_bitspersample == 32 && + tif->tif_postdecode == _TIFFSwab32BitData) + tif->tif_postdecode = _TIFFSwab16BitData; + else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT || + td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) && + td->td_bitspersample == 64 && + tif->tif_postdecode == _TIFFSwab64BitData) + tif->tif_postdecode = _TIFFSwab32BitData; + break; + case TIFFTAG_IMAGEDEPTH: + td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_SUBIFD: + if ((tif->tif_flags & TIFF_INSUBIFD) == 0) + { + td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap); + _TIFFsetLong8Array(tif, &td->td_subifd, + (uint64_t *)va_arg(ap, uint64_t *), + (uint32_t)td->td_nsubifd); + } + else + { + TIFFErrorExtR(tif, module, "%s: Sorry, cannot nest SubIFDs", + tif->tif_name); + status = 0; + } + break; + case TIFFTAG_YCBCRPOSITIONING: + td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_YCBCRSUBSAMPLING: + td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap); + td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_TRANSFERFUNCTION: + { + uint32_t i; + v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; + for (i = 0; i < v; i++) + _TIFFsetShortArrayExt(tif, &td->td_transferfunction[i], + va_arg(ap, uint16_t *), + 1U << td->td_bitspersample); + break; + } + case TIFFTAG_REFERENCEBLACKWHITE: + /* XXX should check for null range */ + _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite, + va_arg(ap, float *), 6); + break; + case TIFFTAG_INKNAMES: + { + v = (uint16_t)va_arg(ap, uint16_vap); + s = va_arg(ap, char *); + uint16_t ninksinstring; + ninksinstring = countInkNamesString(tif, v, s); + status = ninksinstring > 0; + if (ninksinstring > 0) + { + _TIFFsetNString(tif, &td->td_inknames, s, v); + td->td_inknameslen = v; + /* Set NumberOfInks to the value ninksinstring */ + if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) + { + if (td->td_numberofinks != ninksinstring) + { + TIFFErrorExtR( + tif, module, + "Warning %s; Tag %s:\n Value %" PRIu16 + " of NumberOfInks is different from the number of " + "inks %" PRIu16 + ".\n -> NumberOfInks value adapted to %" PRIu16 "", + tif->tif_name, fip->field_name, td->td_numberofinks, + ninksinstring, ninksinstring); + td->td_numberofinks = ninksinstring; + } + } + else + { + td->td_numberofinks = ninksinstring; + TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS); + } + if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) + { + if (td->td_numberofinks != td->td_samplesperpixel) + { + TIFFErrorExtR(tif, module, + "Warning %s; Tag %s:\n Value %" PRIu16 + " of NumberOfInks is different from the " + "SamplesPerPixel value %" PRIu16 "", + tif->tif_name, fip->field_name, + td->td_numberofinks, + td->td_samplesperpixel); + } + } } } - td->td_samplesperpixel = (uint16_t) v; - break; - case TIFFTAG_ROWSPERSTRIP: - v32 = (uint32_t) va_arg(ap, uint32_t); - if (v32 == 0) - goto badvalue32; - td->td_rowsperstrip = v32; - if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { - td->td_tilelength = v32; - td->td_tilewidth = td->td_imagewidth; - } - break; - case TIFFTAG_MINSAMPLEVALUE: - td->td_minsamplevalue = (uint16_t) va_arg(ap, uint16_vap); - break; - case TIFFTAG_MAXSAMPLEVALUE: - td->td_maxsamplevalue = (uint16_t) va_arg(ap, uint16_vap); - break; - case TIFFTAG_SMINSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel); - else - setDoubleArrayOneValue(tif, &td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel); - break; - case TIFFTAG_SMAXSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel); - else - setDoubleArrayOneValue(tif, &td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel); - break; - case TIFFTAG_XRESOLUTION: - dblval = va_arg(ap, double); - if( dblval != dblval || dblval < 0 ) - goto badvaluedouble; - td->td_xresolution = _TIFFClampDoubleToFloat( dblval ); - break; - case TIFFTAG_YRESOLUTION: - dblval = va_arg(ap, double); - if( dblval != dblval || dblval < 0 ) - goto badvaluedouble; - td->td_yresolution = _TIFFClampDoubleToFloat( dblval ); - break; - case TIFFTAG_PLANARCONFIG: - v = (uint16_t) va_arg(ap, uint16_vap); - if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) - goto badvalue; - td->td_planarconfig = (uint16_t) v; - break; - case TIFFTAG_XPOSITION: - td->td_xposition = _TIFFClampDoubleToFloat( va_arg(ap, double) ); - break; - case TIFFTAG_YPOSITION: - td->td_yposition = _TIFFClampDoubleToFloat( va_arg(ap, double) ); - break; - case TIFFTAG_RESOLUTIONUNIT: - v = (uint16_t) va_arg(ap, uint16_vap); - if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) - goto badvalue; - td->td_resolutionunit = (uint16_t) v; - break; - case TIFFTAG_PAGENUMBER: - td->td_pagenumber[0] = (uint16_t) va_arg(ap, uint16_vap); - td->td_pagenumber[1] = (uint16_t) va_arg(ap, uint16_vap); - break; - case TIFFTAG_HALFTONEHINTS: - td->td_halftonehints[0] = (uint16_t) va_arg(ap, uint16_vap); - td->td_halftonehints[1] = (uint16_t) va_arg(ap, uint16_vap); - break; - case TIFFTAG_COLORMAP: - v32 = (uint32_t)(1L << td->td_bitspersample); - _TIFFsetShortArrayExt(tif, &td->td_colormap[0], va_arg(ap, uint16_t*), v32); - _TIFFsetShortArrayExt(tif, &td->td_colormap[1], va_arg(ap, uint16_t*), v32); - _TIFFsetShortArrayExt(tif, &td->td_colormap[2], va_arg(ap, uint16_t*), v32); - break; - case TIFFTAG_EXTRASAMPLES: - if (!setExtraSamples(tif, ap, &v)) - goto badvalue; - break; - case TIFFTAG_MATTEING: - td->td_extrasamples = (((uint16_t) va_arg(ap, uint16_vap)) != 0); - if (td->td_extrasamples) { - uint16_t sv = EXTRASAMPLE_ASSOCALPHA; - _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1); - } - break; - case TIFFTAG_TILEWIDTH: - v32 = (uint32_t) va_arg(ap, uint32_t); - if (v32 % 16) { - if (tif->tif_mode != O_RDONLY) - goto badvalue32; - TIFFWarningExtR(tif, tif->tif_name, - "Nonstandard tile width %"PRIu32", convert file", v32); - } - td->td_tilewidth = v32; - tif->tif_flags |= TIFF_ISTILED; - break; - case TIFFTAG_TILELENGTH: - v32 = (uint32_t) va_arg(ap, uint32_t); - if (v32 % 16) { - if (tif->tif_mode != O_RDONLY) - goto badvalue32; - TIFFWarningExtR(tif, tif->tif_name, - "Nonstandard tile length %"PRIu32", convert file", v32); - } - td->td_tilelength = v32; - tif->tif_flags |= TIFF_ISTILED; - break; - case TIFFTAG_TILEDEPTH: - v32 = (uint32_t) va_arg(ap, uint32_t); - if (v32 == 0) - goto badvalue32; - td->td_tiledepth = v32; - break; - case TIFFTAG_DATATYPE: - v = (uint16_t) va_arg(ap, uint16_vap); - switch (v) { - case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break; - case DATATYPE_INT: v = SAMPLEFORMAT_INT; break; - case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break; - case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break; - default: goto badvalue; - } - td->td_sampleformat = (uint16_t) v; - break; - case TIFFTAG_SAMPLEFORMAT: - v = (uint16_t) va_arg(ap, uint16_vap); - if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) - goto badvalue; - td->td_sampleformat = (uint16_t) v; - - /* Try to fix up the SWAB function for complex data. */ - if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT - && td->td_bitspersample == 32 - && tif->tif_postdecode == _TIFFSwab32BitData ) - tif->tif_postdecode = _TIFFSwab16BitData; - else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT - || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) - && td->td_bitspersample == 64 - && tif->tif_postdecode == _TIFFSwab64BitData ) - tif->tif_postdecode = _TIFFSwab32BitData; - break; - case TIFFTAG_IMAGEDEPTH: - td->td_imagedepth = (uint32_t) va_arg(ap, uint32_t); - break; - case TIFFTAG_SUBIFD: - if ((tif->tif_flags & TIFF_INSUBIFD) == 0) { - td->td_nsubifd = (uint16_t) va_arg(ap, uint16_vap); - _TIFFsetLong8Array(tif, &td->td_subifd, (uint64_t*) va_arg(ap, uint64_t*), - (uint32_t) td->td_nsubifd); - } else { - TIFFErrorExtR(tif, module, - "%s: Sorry, cannot nest SubIFDs", - tif->tif_name); - status = 0; - } - break; - case TIFFTAG_YCBCRPOSITIONING: - td->td_ycbcrpositioning = (uint16_t) va_arg(ap, uint16_vap); - break; - case TIFFTAG_YCBCRSUBSAMPLING: - td->td_ycbcrsubsampling[0] = (uint16_t) va_arg(ap, uint16_vap); - td->td_ycbcrsubsampling[1] = (uint16_t) va_arg(ap, uint16_vap); - break; - case TIFFTAG_TRANSFERFUNCTION: - { - uint32_t i; - v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; - for (i = 0; i < v; i++) - _TIFFsetShortArrayExt(tif, &td->td_transferfunction[i], - va_arg(ap, uint16_t*), 1U << td->td_bitspersample); - break; - } - case TIFFTAG_REFERENCEBLACKWHITE: - /* XXX should check for null range */ - _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite, va_arg(ap, float*), 6); - break; - case TIFFTAG_INKNAMES: - { - v = (uint16_t) va_arg(ap, uint16_vap); - s = va_arg(ap, char*); - uint16_t ninksinstring; - ninksinstring = countInkNamesString(tif, v, s); - status = ninksinstring > 0; - if(ninksinstring > 0 ) { - _TIFFsetNString(tif, &td->td_inknames, s, v); - td->td_inknameslen = v; - /* Set NumberOfInks to the value ninksinstring */ - if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) - { - if (td->td_numberofinks != ninksinstring) { - TIFFErrorExtR(tif, module, - "Warning %s; Tag %s:\n Value %"PRIu16" of NumberOfInks is different from the number of inks %"PRIu16".\n -> NumberOfInks value adapted to %"PRIu16"", - tif->tif_name, fip->field_name, td->td_numberofinks, ninksinstring, ninksinstring); - td->td_numberofinks = ninksinstring; - } - } else { - td->td_numberofinks = ninksinstring; - TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS); - } - if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) - { - if (td->td_numberofinks != td->td_samplesperpixel) { - TIFFErrorExtR(tif, module, - "Warning %s; Tag %s:\n Value %"PRIu16" of NumberOfInks is different from the SamplesPerPixel value %"PRIu16"", - tif->tif_name, fip->field_name, td->td_numberofinks, td->td_samplesperpixel); - } - } - } - } - break; - case TIFFTAG_NUMBEROFINKS: - v = (uint16_t)va_arg(ap, uint16_vap); - /* If InkNames already set also NumberOfInks is set accordingly and should be equal */ - if (TIFFFieldSet(tif, FIELD_INKNAMES)) - { - if (v != td->td_numberofinks) { - TIFFErrorExtR(tif, module, - "Error %s; Tag %s:\n It is not possible to set the value %"PRIu32" for NumberOfInks\n which is different from the number of inks in the InkNames tag (%"PRIu16")", - tif->tif_name, fip->field_name, v, td->td_numberofinks); - /* Do not set / overwrite number of inks already set by InkNames case accordingly. */ - status = 0; - } - } else { - td->td_numberofinks = (uint16_t)v; - if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) - { - if (td->td_numberofinks != td->td_samplesperpixel) { - TIFFErrorExtR(tif, module, - "Warning %s; Tag %s:\n Value %"PRIu32" of NumberOfInks is different from the SamplesPerPixel value %"PRIu16"", - tif->tif_name, fip->field_name, v, td->td_samplesperpixel); - } - } - } - break; - case TIFFTAG_PERSAMPLE: - v = (uint16_t) va_arg(ap, uint16_vap); - if( v == PERSAMPLE_MULTI ) - tif->tif_flags |= TIFF_PERSAMPLE; - else - tif->tif_flags &= ~TIFF_PERSAMPLE; - break; - default: { - TIFFTagValue *tv; - int tv_size, iCustom; - - /* - * This can happen if multiple images are open with different - * codecs which have private tags. The global tag information - * table may then have tags that are valid for one file but not - * the other. If the client tries to set a tag that is not valid - * for the image's codec then we'll arrive here. This - * happens, for example, when tiffcp is used to convert between - * compression schemes and codec-specific tags are blindly copied. - * - * This also happens when a FIELD_IGNORE tag is written. - */ - if (fip->field_bit == FIELD_IGNORE) { - TIFFErrorExtR(tif, module, - "%s: Ignored %stag \"%s\" (not supported by libtiff)", - tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", - fip->field_name); - status = 0; - break; - } - if(fip->field_bit != FIELD_CUSTOM) { - TIFFErrorExtR(tif, module, - "%s: Invalid %stag \"%s\" (not supported by codec)", - tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", - fip->field_name); - status = 0; - break; - } - - /* - * Find the existing entry for this custom value. - */ - tv = NULL; - for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) { - if (td->td_customValues[iCustom].info->field_tag == tag) { - tv = td->td_customValues + iCustom; - if (tv->value != NULL) { - _TIFFfreeExt(tif, tv->value); - tv->value = NULL; - } - break; - } - } - - /* - * Grow the custom list if the entry was not found. - */ - if(tv == NULL) { - TIFFTagValue *new_customValues; - - td->td_customValueCount++; - new_customValues = (TIFFTagValue *) - _TIFFreallocExt(tif, td->td_customValues, - sizeof(TIFFTagValue) * td->td_customValueCount); - if (!new_customValues) { - TIFFErrorExtR(tif, module, - "%s: Failed to allocate space for list of custom values", - tif->tif_name); - status = 0; - goto end; - } - - td->td_customValues = new_customValues; - - tv = td->td_customValues + (td->td_customValueCount - 1); - tv->info = fip; - tv->value = NULL; - tv->count = 0; - } - - /* - * Set custom value ... save a copy of the custom tag value. - */ - /*--: Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ - tv_size = TIFFFieldSetGetSize(fip); - if (tv_size == 0) { - status = 0; - TIFFErrorExtR(tif, module, - "%s: Bad field type %d for \"%s\"", - tif->tif_name, fip->field_type, - fip->field_name); - goto end; - } - - if (fip->field_type == TIFF_ASCII) - { - uint32_t ma; - const char* mb; - if (fip->field_passcount) - { - assert(fip->field_writecount==TIFF_VARIABLE2); - ma=(uint32_t)va_arg(ap, uint32_t); - mb=(const char*)va_arg(ap,const char*); - } - else - { - mb=(const char*)va_arg(ap,const char*); - size_t len = strlen(mb) + 1; - if( len >= 0x80000000U ) - { - status = 0; - TIFFErrorExtR(tif, module, - "%s: Too long string value for \"%s\". " - "Maximum supported is 2147483647 bytes", - tif->tif_name, - fip->field_name); - goto end; - } - ma=(uint32_t)len; - } - tv->count=ma; - setByteArray(tif, &tv->value,mb,ma,1); - } - else - { - if (fip->field_passcount) { - if (fip->field_writecount == TIFF_VARIABLE2) - tv->count = (uint32_t) va_arg(ap, uint32_t); - else - tv->count = (int) va_arg(ap, int); - } else if (fip->field_writecount == TIFF_VARIABLE - || fip->field_writecount == TIFF_VARIABLE2) - tv->count = 1; - else if (fip->field_writecount == TIFF_SPP) - tv->count = td->td_samplesperpixel; - else - tv->count = fip->field_writecount; - - if (tv->count == 0) { - status = 0; - TIFFErrorExtR(tif, module, - "%s: Null count for \"%s\" (type " - "%d, writecount %d, passcount %d)", - tif->tif_name, - fip->field_name, - fip->field_type, - fip->field_writecount, - fip->field_passcount); - goto end; - } - - tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size, - "custom tag binary object"); - if (!tv->value) { - status = 0; - goto end; - } - - if (fip->field_tag == TIFFTAG_DOTRANGE - && strcmp(fip->field_name,"DotRange") == 0) { - /* TODO: This is an evil exception and should not have been - handled this way ... likely best if we move it into - the directory structure with an explicit field in - libtiff 4.1 and assign it a FIELD_ value */ - uint16_t v2[2]; - v2[0] = (uint16_t)va_arg(ap, int); - v2[1] = (uint16_t)va_arg(ap, int); - _TIFFmemcpy(tv->value, &v2, 4); - } - - else if (fip->field_passcount - || fip->field_writecount == TIFF_VARIABLE - || fip->field_writecount == TIFF_VARIABLE2 - || fip->field_writecount == TIFF_SPP - || tv->count > 1) { - /*--: Rational2Double: For Rationals tv_size is set above to 4 or 8 according to fip->set_field_type! */ - _TIFFmemcpy(tv->value, va_arg(ap, void *), - tv->count * tv_size); - /* Test here for too big values for LONG8, SLONG8 in ClassicTIFF and delete custom field from custom list */ - if (!(tif->tif_flags & TIFF_BIGTIFF)) { - if (tv->info->field_type == TIFF_LONG8) { - uint64_t *pui64 = (uint64_t *)tv->value; - for (int i = 0; i < tv->count; i++) { - if (pui64[i] > 0xffffffffu) { - TIFFErrorExtR(tif, module, - "%s: Bad LONG8 value %"PRIu64" at %d. array position for \"%s\" tag %d in ClassicTIFF. Tag won't be written to file", - tif->tif_name, pui64[i], i, fip->field_name, tag); - goto badvalueifd8long8; - } - } - } else if (tv->info->field_type == TIFF_SLONG8) { - int64_t *pi64 = (int64_t *)tv->value; - for (int i = 0; i < tv->count; i++) { - if (pi64[i] > 2147483647 || pi64[i] < (-2147483647 - 1)) { - TIFFErrorExtR(tif, module, - "%s: Bad SLONG8 value %"PRIi64" at %d. array position for \"%s\" tag %d in ClassicTIFF. Tag won't be written to file", - tif->tif_name, pi64[i], i, fip->field_name, tag); - goto badvalueifd8long8; - } - } - } - } - } else { - char *val = (char *)tv->value; - assert( tv->count == 1 ); - - switch (fip->field_type) { - case TIFF_BYTE: - case TIFF_UNDEFINED: - { - uint8_t v2 = (uint8_t)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SBYTE: - { - int8_t v2 = (int8_t)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SHORT: - { - uint16_t v2 = (uint16_t)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SSHORT: - { - int16_t v2 = (int16_t)va_arg(ap, int); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_LONG: - case TIFF_IFD: - { - uint32_t v2 = va_arg(ap, uint32_t); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_SLONG: - { - int32_t v2 = va_arg(ap, int32_t); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_LONG8: - case TIFF_IFD8: - { - uint64_t v2 = va_arg(ap, uint64_t); - _TIFFmemcpy(val, &v2, tv_size); - /* Test here for too big values for ClassicTIFF and delete custom field from custom list */ - if (!(tif->tif_flags & TIFF_BIGTIFF) && (v2 > 0xffffffffu)) { - TIFFErrorExtR(tif, module, - "%s: Bad LONG8 or IFD8 value %"PRIu64" for \"%s\" tag %d in ClassicTIFF. Tag won't be written to file", - tif->tif_name, v2, fip->field_name, tag); - goto badvalueifd8long8; - } - } - break; - case TIFF_SLONG8: - { - int64_t v2 = va_arg(ap, int64_t); - _TIFFmemcpy(val, &v2, tv_size); - /* Test here for too big values for ClassicTIFF and delete custom field from custom list */ - if (!(tif->tif_flags & TIFF_BIGTIFF) && ((v2 > 2147483647) || (v2 < (-2147483647 - 1)))) { - TIFFErrorExtR(tif, module, - "%s: Bad SLONG8 value %"PRIi64" for \"%s\" tag %d in ClassicTIFF. Tag won't be written to file", - tif->tif_name, v2, fip->field_name, tag); - goto badvalueifd8long8; - } - } - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - /*-- Rational2Double: For Rationals tv_size is set above to 4 or 8 according to fip->set_field_type! */ - { - if (tv_size == 8) { - double v2 = va_arg(ap, double); - _TIFFmemcpy(val, &v2, tv_size); - } else { - /*-- default should be tv_size == 4 */ - float v3 = (float)va_arg(ap, double); - _TIFFmemcpy(val, &v3, tv_size); - /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */ - if (tv_size != 4) { - TIFFErrorExtR(tif, module, "Rational2Double: .set_field_type in not 4 but %d", tv_size); - } - } - } - break; - case TIFF_FLOAT: - { - float v2 = _TIFFClampDoubleToFloat(va_arg(ap, double)); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - case TIFF_DOUBLE: - { - double v2 = va_arg(ap, double); - _TIFFmemcpy(val, &v2, tv_size); - } - break; - default: - _TIFFmemset(val, 0, tv_size); - status = 0; - break; - } - } - } - } - } - if (status) { - const TIFFField* fip2=TIFFFieldWithTag(tif,tag); - if (fip2) - TIFFSetFieldBit(tif, fip2->field_bit); - tif->tif_flags |= TIFF_DIRTYDIRECT; - } + break; + case TIFFTAG_NUMBEROFINKS: + v = (uint16_t)va_arg(ap, uint16_vap); + /* If InkNames already set also NumberOfInks is set accordingly and + * should be equal */ + if (TIFFFieldSet(tif, FIELD_INKNAMES)) + { + if (v != td->td_numberofinks) + { + TIFFErrorExtR( + tif, module, + "Error %s; Tag %s:\n It is not possible to set the " + "value %" PRIu32 + " for NumberOfInks\n which is different from the " + "number of inks in the InkNames tag (%" PRIu16 ")", + tif->tif_name, fip->field_name, v, td->td_numberofinks); + /* Do not set / overwrite number of inks already set by + * InkNames case accordingly. */ + status = 0; + } + } + else + { + td->td_numberofinks = (uint16_t)v; + if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) + { + if (td->td_numberofinks != td->td_samplesperpixel) + { + TIFFErrorExtR(tif, module, + "Warning %s; Tag %s:\n Value %" PRIu32 + " of NumberOfInks is different from the " + "SamplesPerPixel value %" PRIu16 "", + tif->tif_name, fip->field_name, v, + td->td_samplesperpixel); + } + } + } + break; + case TIFFTAG_PERSAMPLE: + v = (uint16_t)va_arg(ap, uint16_vap); + if (v == PERSAMPLE_MULTI) + tif->tif_flags |= TIFF_PERSAMPLE; + else + tif->tif_flags &= ~TIFF_PERSAMPLE; + break; + default: + { + TIFFTagValue *tv; + int tv_size, iCustom; + + /* + * This can happen if multiple images are open with different + * codecs which have private tags. The global tag information + * table may then have tags that are valid for one file but not + * the other. If the client tries to set a tag that is not valid + * for the image's codec then we'll arrive here. This + * happens, for example, when tiffcp is used to convert between + * compression schemes and codec-specific tags are blindly copied. + * + * This also happens when a FIELD_IGNORE tag is written. + */ + if (fip->field_bit == FIELD_IGNORE) + { + TIFFErrorExtR( + tif, module, + "%s: Ignored %stag \"%s\" (not supported by libtiff)", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", + fip->field_name); + status = 0; + break; + } + if (fip->field_bit != FIELD_CUSTOM) + { + TIFFErrorExtR( + tif, module, + "%s: Invalid %stag \"%s\" (not supported by codec)", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", + fip->field_name); + status = 0; + break; + } + + /* + * Find the existing entry for this custom value. + */ + tv = NULL; + for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) + { + if (td->td_customValues[iCustom].info->field_tag == tag) + { + tv = td->td_customValues + iCustom; + if (tv->value != NULL) + { + _TIFFfreeExt(tif, tv->value); + tv->value = NULL; + } + break; + } + } + + /* + * Grow the custom list if the entry was not found. + */ + if (tv == NULL) + { + TIFFTagValue *new_customValues; + + td->td_customValueCount++; + new_customValues = (TIFFTagValue *)_TIFFreallocExt( + tif, td->td_customValues, + sizeof(TIFFTagValue) * td->td_customValueCount); + if (!new_customValues) + { + TIFFErrorExtR(tif, module, + "%s: Failed to allocate space for list of " + "custom values", + tif->tif_name); + status = 0; + goto end; + } + + td->td_customValues = new_customValues; + + tv = td->td_customValues + (td->td_customValueCount - 1); + tv->info = fip; + tv->value = NULL; + tv->count = 0; + } + + /* + * Set custom value ... save a copy of the custom tag value. + */ + /*--: Rational2Double: For Rationals evaluate "set_field_type" to + * determine internal storage size. */ + tv_size = TIFFFieldSetGetSize(fip); + if (tv_size == 0) + { + status = 0; + TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"", + tif->tif_name, fip->field_type, fip->field_name); + goto end; + } + + if (fip->field_type == TIFF_ASCII) + { + uint32_t ma; + const char *mb; + if (fip->field_passcount) + { + assert(fip->field_writecount == TIFF_VARIABLE2); + ma = (uint32_t)va_arg(ap, uint32_t); + mb = (const char *)va_arg(ap, const char *); + } + else + { + mb = (const char *)va_arg(ap, const char *); + size_t len = strlen(mb) + 1; + if (len >= 0x80000000U) + { + status = 0; + TIFFErrorExtR(tif, module, + "%s: Too long string value for \"%s\". " + "Maximum supported is 2147483647 bytes", + tif->tif_name, fip->field_name); + goto end; + } + ma = (uint32_t)len; + } + tv->count = ma; + setByteArray(tif, &tv->value, mb, ma, 1); + } + else + { + if (fip->field_passcount) + { + if (fip->field_writecount == TIFF_VARIABLE2) + tv->count = (uint32_t)va_arg(ap, uint32_t); + else + tv->count = (int)va_arg(ap, int); + } + else if (fip->field_writecount == TIFF_VARIABLE || + fip->field_writecount == TIFF_VARIABLE2) + tv->count = 1; + else if (fip->field_writecount == TIFF_SPP) + tv->count = td->td_samplesperpixel; + else + tv->count = fip->field_writecount; + + if (tv->count == 0) + { + status = 0; + TIFFErrorExtR(tif, module, + "%s: Null count for \"%s\" (type " + "%d, writecount %d, passcount %d)", + tif->tif_name, fip->field_name, + fip->field_type, fip->field_writecount, + fip->field_passcount); + goto end; + } + + tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size, + "custom tag binary object"); + if (!tv->value) + { + status = 0; + goto end; + } + + if (fip->field_tag == TIFFTAG_DOTRANGE && + strcmp(fip->field_name, "DotRange") == 0) + { + /* TODO: This is an evil exception and should not have been + handled this way ... likely best if we move it into + the directory structure with an explicit field in + libtiff 4.1 and assign it a FIELD_ value */ + uint16_t v2[2]; + v2[0] = (uint16_t)va_arg(ap, int); + v2[1] = (uint16_t)va_arg(ap, int); + _TIFFmemcpy(tv->value, &v2, 4); + } + + else if (fip->field_passcount || + fip->field_writecount == TIFF_VARIABLE || + fip->field_writecount == TIFF_VARIABLE2 || + fip->field_writecount == TIFF_SPP || tv->count > 1) + { + /*--: Rational2Double: For Rationals tv_size is set above to + * 4 or 8 according to fip->set_field_type! */ + _TIFFmemcpy(tv->value, va_arg(ap, void *), + tv->count * tv_size); + /* Test here for too big values for LONG8, SLONG8 in + * ClassicTIFF and delete custom field from custom list */ + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + if (tv->info->field_type == TIFF_LONG8) + { + uint64_t *pui64 = (uint64_t *)tv->value; + for (int i = 0; i < tv->count; i++) + { + if (pui64[i] > 0xffffffffu) + { + TIFFErrorExtR( + tif, module, + "%s: Bad LONG8 value %" PRIu64 + " at %d. array position for \"%s\" tag " + "%d in ClassicTIFF. Tag won't be " + "written to file", + tif->tif_name, pui64[i], i, + fip->field_name, tag); + goto badvalueifd8long8; + } + } + } + else if (tv->info->field_type == TIFF_SLONG8) + { + int64_t *pi64 = (int64_t *)tv->value; + for (int i = 0; i < tv->count; i++) + { + if (pi64[i] > 2147483647 || + pi64[i] < (-2147483647 - 1)) + { + TIFFErrorExtR( + tif, module, + "%s: Bad SLONG8 value %" PRIi64 + " at %d. array position for \"%s\" tag " + "%d in ClassicTIFF. Tag won't be " + "written to file", + tif->tif_name, pi64[i], i, + fip->field_name, tag); + goto badvalueifd8long8; + } + } + } + } + } + else + { + char *val = (char *)tv->value; + assert(tv->count == 1); + + switch (fip->field_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + { + uint8_t v2 = (uint8_t)va_arg(ap, int); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_SBYTE: + { + int8_t v2 = (int8_t)va_arg(ap, int); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_SHORT: + { + uint16_t v2 = (uint16_t)va_arg(ap, int); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_SSHORT: + { + int16_t v2 = (int16_t)va_arg(ap, int); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_LONG: + case TIFF_IFD: + { + uint32_t v2 = va_arg(ap, uint32_t); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_SLONG: + { + int32_t v2 = va_arg(ap, int32_t); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_LONG8: + case TIFF_IFD8: + { + uint64_t v2 = va_arg(ap, uint64_t); + _TIFFmemcpy(val, &v2, tv_size); + /* Test here for too big values for ClassicTIFF and + * delete custom field from custom list */ + if (!(tif->tif_flags & TIFF_BIGTIFF) && + (v2 > 0xffffffffu)) + { + TIFFErrorExtR( + tif, module, + "%s: Bad LONG8 or IFD8 value %" PRIu64 + " for \"%s\" tag %d in ClassicTIFF. Tag " + "won't be written to file", + tif->tif_name, v2, fip->field_name, tag); + goto badvalueifd8long8; + } + } + break; + case TIFF_SLONG8: + { + int64_t v2 = va_arg(ap, int64_t); + _TIFFmemcpy(val, &v2, tv_size); + /* Test here for too big values for ClassicTIFF and + * delete custom field from custom list */ + if (!(tif->tif_flags & TIFF_BIGTIFF) && + ((v2 > 2147483647) || (v2 < (-2147483647 - 1)))) + { + TIFFErrorExtR( + tif, module, + "%s: Bad SLONG8 value %" PRIi64 + " for \"%s\" tag %d in ClassicTIFF. Tag " + "won't be written to file", + tif->tif_name, v2, fip->field_name, tag); + goto badvalueifd8long8; + } + } + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + /*-- Rational2Double: For Rationals tv_size is set + * above to 4 or 8 according to fip->set_field_type! + */ + { + if (tv_size == 8) + { + double v2 = va_arg(ap, double); + _TIFFmemcpy(val, &v2, tv_size); + } + else + { + /*-- default should be tv_size == 4 */ + float v3 = (float)va_arg(ap, double); + _TIFFmemcpy(val, &v3, tv_size); + /*-- ToDo: After Testing, this should be + * removed and tv_size==4 should be set as + * default. */ + if (tv_size != 4) + { + TIFFErrorExtR( + tif, module, + "Rational2Double: .set_field_type " + "in not 4 but %d", + tv_size); + } + } + } + break; + case TIFF_FLOAT: + { + float v2 = + _TIFFClampDoubleToFloat(va_arg(ap, double)); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + case TIFF_DOUBLE: + { + double v2 = va_arg(ap, double); + _TIFFmemcpy(val, &v2, tv_size); + } + break; + default: + _TIFFmemset(val, 0, tv_size); + status = 0; + break; + } + } + } + } + } + if (status) + { + const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); + if (fip2) + TIFFSetFieldBit(tif, fip2->field_bit); + tif->tif_flags |= TIFF_DIRTYDIRECT; + } end: - va_end(ap); - return (status); + va_end(ap); + return (status); badvalue: +{ + const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); + TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag", + tif->tif_name, v, fip2 ? fip2->field_name : "Unknown"); + va_end(ap); +} + return (0); +badvalue32: +{ + const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); + TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag", + tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown"); + va_end(ap); +} + return (0); +badvaluedouble: +{ + const TIFFField *fip2 = TIFFFieldWithTag(tif, tag); + TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name, + dblval, fip2 ? fip2->field_name : "Unknown"); + va_end(ap); +} + return (0); +badvalueifd8long8: +{ + /* Error message issued already above. */ + TIFFTagValue *tv2 = NULL; + int iCustom2, iC2; + /* Find the existing entry for this custom value. */ + for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++) + { + if (td->td_customValues[iCustom2].info->field_tag == tag) { - const TIFFField* fip2=TIFFFieldWithTag(tif,tag); - TIFFErrorExtR(tif, module, - "%s: Bad value %"PRIu32" for \"%s\" tag", - tif->tif_name, v, - fip2 ? fip2->field_name : "Unknown"); - va_end(ap); + tv2 = td->td_customValues + (iCustom2); + break; } - return (0); -badvalue32: + } + if (tv2 != NULL) + { + /* Remove custom field from custom list */ + if (tv2->value != NULL) { - const TIFFField* fip2=TIFFFieldWithTag(tif,tag); - TIFFErrorExtR(tif, module, - "%s: Bad value %"PRIu32" for \"%s\" tag", - tif->tif_name, v32, - fip2 ? fip2->field_name : "Unknown"); - va_end(ap); + _TIFFfreeExt(tif, tv2->value); + tv2->value = NULL; } - return (0); -badvaluedouble: + /* Shorten list and close gap in customValues list. + * Re-allocation of td_customValues not necessary here. */ + td->td_customValueCount--; + for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++) { - const TIFFField* fip2=TIFFFieldWithTag(tif,tag); - TIFFErrorExtR(tif, module, - "%s: Bad value %f for \"%s\" tag", - tif->tif_name, dblval, - fip2 ? fip2->field_name : "Unknown"); - va_end(ap); + td->td_customValues[iC2] = td->td_customValues[iC2 + 1]; } + } + else + { + assert(0); + } + va_end(ap); +} return (0); -badvalueifd8long8: - { - /* Error message issued already above. */ - TIFFTagValue *tv2 = NULL; - int iCustom2, iC2; - /* Find the existing entry for this custom value. */ - for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++) { - if (td->td_customValues[iCustom2].info->field_tag == tag) { - tv2 = td->td_customValues + (iCustom2); - break; - } - } - if (tv2 != NULL) { - /* Remove custom field from custom list */ - if (tv2->value != NULL) { - _TIFFfreeExt(tif, tv2->value); - tv2->value = NULL; - } - /* Shorten list and close gap in customValues list. - * Re-allocation of td_customValues not necessary here. */ - td->td_customValueCount--; - for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++) { - td->td_customValues[iC2] = td->td_customValues[iC2+1]; - } - } else { - assert(0); - } - va_end(ap); - } - return (0); } /*-- _TIFFVSetField() --*/ /* @@ -941,29 +1109,30 @@ badvalueifd8long8: * has commenced, unless its value has no effect * on the format of the data that is written. */ -static int -OkToChangeTag(TIFF* tif, uint32_t tag) +static int OkToChangeTag(TIFF *tif, uint32_t tag) { - const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); - if (!fip) { /* unknown tag */ - TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %"PRIu32, - tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); - return (0); - } - if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && - !fip->field_oktochange) { - /* - * Consult info table to see if tag can be changed - * after we've started writing. We only allow changes - * to those tags that don't/shouldn't affect the - * compression and/or format of the data. - */ - TIFFErrorExtR(tif, "TIFFSetField", - "%s: Cannot modify tag \"%s\" while writing", - tif->tif_name, fip->field_name); - return (0); - } - return (1); + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + if (!fip) + { /* unknown tag */ + TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32, + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); + return (0); + } + if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && + !fip->field_oktochange) + { + /* + * Consult info table to see if tag can be changed + * after we've started writing. We only allow changes + * to those tags that don't/shouldn't affect the + * compression and/or format of the data. + */ + TIFFErrorExtR(tif, "TIFFSetField", + "%s: Cannot modify tag \"%s\" while writing", + tif->tif_name, fip->field_name); + return (0); + } + return (1); } /* @@ -973,54 +1142,54 @@ OkToChangeTag(TIFF* tif, uint32_t tag) * when/if the directory structure is * updated. */ -int -TIFFSetField(TIFF* tif, uint32_t tag, ...) +int TIFFSetField(TIFF *tif, uint32_t tag, ...) { - va_list ap; - int status; + va_list ap; + int status; - va_start(ap, tag); - status = TIFFVSetField(tif, tag, ap); - va_end(ap); - return (status); + va_start(ap, tag); + status = TIFFVSetField(tif, tag, ap); + va_end(ap); + return (status); } /* * Clear the contents of the field in the internal structure. */ -int -TIFFUnsetField(TIFF* tif, uint32_t tag) +int TIFFUnsetField(TIFF *tif, uint32_t tag) { - const TIFFField *fip = TIFFFieldWithTag(tif, tag); - TIFFDirectory* td = &tif->tif_dir; + const TIFFField *fip = TIFFFieldWithTag(tif, tag); + TIFFDirectory *td = &tif->tif_dir; - if( !fip ) + if (!fip) return 0; - if( fip->field_bit != FIELD_CUSTOM ) + if (fip->field_bit != FIELD_CUSTOM) TIFFClrFieldBit(tif, fip->field_bit); else { TIFFTagValue *tv = NULL; int i; - for (i = 0; i < td->td_customValueCount; i++) { - + for (i = 0; i < td->td_customValueCount; i++) + { + tv = td->td_customValues + i; - if( tv->info->field_tag == tag ) + if (tv->info->field_tag == tag) break; } - if( i < td->td_customValueCount ) + if (i < td->td_customValueCount) { _TIFFfreeExt(tif, tv->value); - for( ; i < td->td_customValueCount-1; i++) { - td->td_customValues[i] = td->td_customValues[i+1]; + for (; i < td->td_customValueCount - 1; i++) + { + td->td_customValues[i] = td->td_customValues[i + 1]; } td->td_customValueCount--; } } - + tif->tif_flags |= TIFF_DIRTYDIRECT; return (1); @@ -1032,378 +1201,392 @@ TIFFUnsetField(TIFF* tif, uint32_t tag) * for building higher-level interfaces on * top of the library. */ -int -TIFFVSetField(TIFF* tif, uint32_t tag, va_list ap) +int TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap) { - return OkToChangeTag(tif, tag) ? - (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0; + return OkToChangeTag(tif, tag) + ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) + : 0; } -static int -_TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap) +static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap) { - TIFFDirectory* td = &tif->tif_dir; - int ret_val = 1; - uint32_t standard_tag = tag; - const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); - if( fip == NULL ) /* cannot happen since TIFFGetField() already checks it */ - return 0; - - /* - * We want to force the custom code to be used for custom - * fields even if the tag happens to match a well known - * one - important for reinterpreted handling of standard - * tag values in custom directories (i.e. EXIF) - */ - if (fip->field_bit == FIELD_CUSTOM) { - standard_tag = 0; - } - - switch (standard_tag) { - case TIFFTAG_SUBFILETYPE: - *va_arg(ap, uint32_t*) = td->td_subfiletype; - break; - case TIFFTAG_IMAGEWIDTH: - *va_arg(ap, uint32_t*) = td->td_imagewidth; - break; - case TIFFTAG_IMAGELENGTH: - *va_arg(ap, uint32_t*) = td->td_imagelength; - break; - case TIFFTAG_BITSPERSAMPLE: - *va_arg(ap, uint16_t*) = td->td_bitspersample; - break; - case TIFFTAG_COMPRESSION: - *va_arg(ap, uint16_t*) = td->td_compression; - break; - case TIFFTAG_PHOTOMETRIC: - *va_arg(ap, uint16_t*) = td->td_photometric; - break; - case TIFFTAG_THRESHHOLDING: - *va_arg(ap, uint16_t*) = td->td_threshholding; - break; - case TIFFTAG_FILLORDER: - *va_arg(ap, uint16_t*) = td->td_fillorder; - break; - case TIFFTAG_ORIENTATION: - *va_arg(ap, uint16_t*) = td->td_orientation; - break; - case TIFFTAG_SAMPLESPERPIXEL: - *va_arg(ap, uint16_t*) = td->td_samplesperpixel; - break; - case TIFFTAG_ROWSPERSTRIP: - *va_arg(ap, uint32_t*) = td->td_rowsperstrip; - break; - case TIFFTAG_MINSAMPLEVALUE: - *va_arg(ap, uint16_t*) = td->td_minsamplevalue; - break; - case TIFFTAG_MAXSAMPLEVALUE: - *va_arg(ap, uint16_t*) = td->td_maxsamplevalue; - break; - case TIFFTAG_SMINSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - *va_arg(ap, double**) = td->td_sminsamplevalue; - else - { - /* libtiff historically treats this as a single value. */ - uint16_t i; - double v = td->td_sminsamplevalue[0]; - for (i=1; i < td->td_samplesperpixel; ++i) - if( td->td_sminsamplevalue[i] < v ) - v = td->td_sminsamplevalue[i]; - *va_arg(ap, double*) = v; - } - break; - case TIFFTAG_SMAXSAMPLEVALUE: - if (tif->tif_flags & TIFF_PERSAMPLE) - *va_arg(ap, double**) = td->td_smaxsamplevalue; - else - { - /* libtiff historically treats this as a single value. */ - uint16_t i; - double v = td->td_smaxsamplevalue[0]; - for (i=1; i < td->td_samplesperpixel; ++i) - if( td->td_smaxsamplevalue[i] > v ) - v = td->td_smaxsamplevalue[i]; - *va_arg(ap, double*) = v; - } - break; - case TIFFTAG_XRESOLUTION: - *va_arg(ap, float*) = td->td_xresolution; - break; - case TIFFTAG_YRESOLUTION: - *va_arg(ap, float*) = td->td_yresolution; - break; - case TIFFTAG_PLANARCONFIG: - *va_arg(ap, uint16_t*) = td->td_planarconfig; - break; - case TIFFTAG_XPOSITION: - *va_arg(ap, float*) = td->td_xposition; - break; - case TIFFTAG_YPOSITION: - *va_arg(ap, float*) = td->td_yposition; - break; - case TIFFTAG_RESOLUTIONUNIT: - *va_arg(ap, uint16_t*) = td->td_resolutionunit; - break; - case TIFFTAG_PAGENUMBER: - *va_arg(ap, uint16_t*) = td->td_pagenumber[0]; - *va_arg(ap, uint16_t*) = td->td_pagenumber[1]; - break; - case TIFFTAG_HALFTONEHINTS: - *va_arg(ap, uint16_t*) = td->td_halftonehints[0]; - *va_arg(ap, uint16_t*) = td->td_halftonehints[1]; - break; - case TIFFTAG_COLORMAP: - *va_arg(ap, const uint16_t**) = td->td_colormap[0]; - *va_arg(ap, const uint16_t**) = td->td_colormap[1]; - *va_arg(ap, const uint16_t**) = td->td_colormap[2]; - break; - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_TILEOFFSETS: - _TIFFFillStriles( tif ); - *va_arg(ap, const uint64_t**) = td->td_stripoffset_p; - if( td->td_stripoffset_p == NULL ) - ret_val = 0; - break; - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEBYTECOUNTS: - _TIFFFillStriles( tif ); - *va_arg(ap, const uint64_t**) = td->td_stripbytecount_p; - if( td->td_stripbytecount_p == NULL ) - ret_val = 0; - break; - case TIFFTAG_MATTEING: - *va_arg(ap, uint16_t*) = - (td->td_extrasamples == 1 && - td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); - break; - case TIFFTAG_EXTRASAMPLES: - *va_arg(ap, uint16_t*) = td->td_extrasamples; - *va_arg(ap, const uint16_t**) = td->td_sampleinfo; - break; - case TIFFTAG_TILEWIDTH: - *va_arg(ap, uint32_t*) = td->td_tilewidth; - break; - case TIFFTAG_TILELENGTH: - *va_arg(ap, uint32_t*) = td->td_tilelength; - break; - case TIFFTAG_TILEDEPTH: - *va_arg(ap, uint32_t*) = td->td_tiledepth; - break; - case TIFFTAG_DATATYPE: - switch (td->td_sampleformat) { - case SAMPLEFORMAT_UINT: - *va_arg(ap, uint16_t*) = DATATYPE_UINT; - break; - case SAMPLEFORMAT_INT: - *va_arg(ap, uint16_t*) = DATATYPE_INT; - break; - case SAMPLEFORMAT_IEEEFP: - *va_arg(ap, uint16_t*) = DATATYPE_IEEEFP; - break; - case SAMPLEFORMAT_VOID: - *va_arg(ap, uint16_t*) = DATATYPE_VOID; - break; - } - break; - case TIFFTAG_SAMPLEFORMAT: - *va_arg(ap, uint16_t*) = td->td_sampleformat; - break; - case TIFFTAG_IMAGEDEPTH: - *va_arg(ap, uint32_t*) = td->td_imagedepth; - break; - case TIFFTAG_SUBIFD: - *va_arg(ap, uint16_t*) = td->td_nsubifd; - *va_arg(ap, const uint64_t**) = td->td_subifd; - break; - case TIFFTAG_YCBCRPOSITIONING: - *va_arg(ap, uint16_t*) = td->td_ycbcrpositioning; - break; - case TIFFTAG_YCBCRSUBSAMPLING: - *va_arg(ap, uint16_t*) = td->td_ycbcrsubsampling[0]; - *va_arg(ap, uint16_t*) = td->td_ycbcrsubsampling[1]; - break; - case TIFFTAG_TRANSFERFUNCTION: - *va_arg(ap, const uint16_t**) = td->td_transferfunction[0]; - if (td->td_samplesperpixel - td->td_extrasamples > 1) { - *va_arg(ap, const uint16_t**) = td->td_transferfunction[1]; - *va_arg(ap, const uint16_t**) = td->td_transferfunction[2]; - } else { - *va_arg(ap, const uint16_t**) = NULL; - *va_arg(ap, const uint16_t**) = NULL; - } - break; - case TIFFTAG_REFERENCEBLACKWHITE: - *va_arg(ap, const float**) = td->td_refblackwhite; - break; - case TIFFTAG_INKNAMES: - *va_arg(ap, const char**) = td->td_inknames; - break; - case TIFFTAG_NUMBEROFINKS: - *va_arg(ap, uint16_t *) = td->td_numberofinks; - break; - default: - { - int i; - - /* - * This can happen if multiple images are open - * with different codecs which have private - * tags. The global tag information table may - * then have tags that are valid for one file - * but not the other. If the client tries to - * get a tag that is not valid for the image's - * codec then we'll arrive here. - */ - if( fip->field_bit != FIELD_CUSTOM ) - { - TIFFErrorExtR(tif, "_TIFFVGetField", - "%s: Invalid %stag \"%s\" " - "(not supported by codec)", - tif->tif_name, - isPseudoTag(tag) ? "pseudo-" : "", - fip->field_name); - ret_val = 0; - break; - } - - /* - * Do we have a custom value? - */ - ret_val = 0; - for (i = 0; i < td->td_customValueCount; i++) { - TIFFTagValue *tv = td->td_customValues + i; - - if (tv->info->field_tag != tag) - continue; - - if (fip->field_passcount) { - if (fip->field_readcount == TIFF_VARIABLE2) - *va_arg(ap, uint32_t*) = (uint32_t)tv->count; - else /* Assume TIFF_VARIABLE */ - *va_arg(ap, uint16_t*) = (uint16_t)tv->count; - *va_arg(ap, const void **) = tv->value; - ret_val = 1; - } else if (fip->field_tag == TIFFTAG_DOTRANGE - && strcmp(fip->field_name,"DotRange") == 0) { - /* TODO: This is an evil exception and should not have been - handled this way ... likely best if we move it into - the directory structure with an explicit field in - libtiff 4.1 and assign it a FIELD_ value */ - *va_arg(ap, uint16_t*) = ((uint16_t *)tv->value)[0]; - *va_arg(ap, uint16_t*) = ((uint16_t *)tv->value)[1]; - ret_val = 1; - } else { - if (fip->field_type == TIFF_ASCII - || fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2 - || fip->field_readcount == TIFF_SPP - || tv->count > 1) { - *va_arg(ap, void **) = tv->value; - ret_val = 1; - } else { - char *val = (char *)tv->value; - assert( tv->count == 1 ); - switch (fip->field_type) { - case TIFF_BYTE: - case TIFF_UNDEFINED: - *va_arg(ap, uint8_t*) = - *(uint8_t *)val; - ret_val = 1; - break; - case TIFF_SBYTE: - *va_arg(ap, int8_t*) = - *(int8_t *)val; - ret_val = 1; - break; - case TIFF_SHORT: - *va_arg(ap, uint16_t*) = - *(uint16_t *)val; - ret_val = 1; - break; - case TIFF_SSHORT: - *va_arg(ap, int16_t*) = - *(int16_t *)val; - ret_val = 1; - break; - case TIFF_LONG: - case TIFF_IFD: - *va_arg(ap, uint32_t*) = - *(uint32_t *)val; - ret_val = 1; - break; - case TIFF_SLONG: - *va_arg(ap, int32_t*) = - *(int32_t *)val; - ret_val = 1; - break; - case TIFF_LONG8: - case TIFF_IFD8: - *va_arg(ap, uint64_t*) = - *(uint64_t *)val; - ret_val = 1; - break; - case TIFF_SLONG8: - *va_arg(ap, int64_t*) = - *(int64_t *)val; - ret_val = 1; - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - { - /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size and return value size. */ - int tv_size = TIFFFieldSetGetSize(fip); - if (tv_size == 8) { - *va_arg(ap, double*) = *(double *)val; - ret_val = 1; - } else { - /*-- default should be tv_size == 4 */ - *va_arg(ap, float*) = *(float *)val; - ret_val = 1; - /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */ - if (tv_size != 4) { - TIFFErrorExtR(tif, "_TIFFVGetField", "Rational2Double: .set_field_type in not 4 but %d", tv_size); - } - } - } - break; - case TIFF_FLOAT: - *va_arg(ap, float*) = - *(float *)val; - ret_val = 1; - break; - case TIFF_DOUBLE: - *va_arg(ap, double*) = - *(double *)val; - ret_val = 1; - break; - default: - ret_val = 0; - break; - } - } - } - break; - } - } - } - return(ret_val); + TIFFDirectory *td = &tif->tif_dir; + int ret_val = 1; + uint32_t standard_tag = tag; + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + if (fip == NULL) /* cannot happen since TIFFGetField() already checks it */ + return 0; + + /* + * We want to force the custom code to be used for custom + * fields even if the tag happens to match a well known + * one - important for reinterpreted handling of standard + * tag values in custom directories (i.e. EXIF) + */ + if (fip->field_bit == FIELD_CUSTOM) + { + standard_tag = 0; + } + + switch (standard_tag) + { + case TIFFTAG_SUBFILETYPE: + *va_arg(ap, uint32_t *) = td->td_subfiletype; + break; + case TIFFTAG_IMAGEWIDTH: + *va_arg(ap, uint32_t *) = td->td_imagewidth; + break; + case TIFFTAG_IMAGELENGTH: + *va_arg(ap, uint32_t *) = td->td_imagelength; + break; + case TIFFTAG_BITSPERSAMPLE: + *va_arg(ap, uint16_t *) = td->td_bitspersample; + break; + case TIFFTAG_COMPRESSION: + *va_arg(ap, uint16_t *) = td->td_compression; + break; + case TIFFTAG_PHOTOMETRIC: + *va_arg(ap, uint16_t *) = td->td_photometric; + break; + case TIFFTAG_THRESHHOLDING: + *va_arg(ap, uint16_t *) = td->td_threshholding; + break; + case TIFFTAG_FILLORDER: + *va_arg(ap, uint16_t *) = td->td_fillorder; + break; + case TIFFTAG_ORIENTATION: + *va_arg(ap, uint16_t *) = td->td_orientation; + break; + case TIFFTAG_SAMPLESPERPIXEL: + *va_arg(ap, uint16_t *) = td->td_samplesperpixel; + break; + case TIFFTAG_ROWSPERSTRIP: + *va_arg(ap, uint32_t *) = td->td_rowsperstrip; + break; + case TIFFTAG_MINSAMPLEVALUE: + *va_arg(ap, uint16_t *) = td->td_minsamplevalue; + break; + case TIFFTAG_MAXSAMPLEVALUE: + *va_arg(ap, uint16_t *) = td->td_maxsamplevalue; + break; + case TIFFTAG_SMINSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + *va_arg(ap, double **) = td->td_sminsamplevalue; + else + { + /* libtiff historically treats this as a single value. */ + uint16_t i; + double v = td->td_sminsamplevalue[0]; + for (i = 1; i < td->td_samplesperpixel; ++i) + if (td->td_sminsamplevalue[i] < v) + v = td->td_sminsamplevalue[i]; + *va_arg(ap, double *) = v; + } + break; + case TIFFTAG_SMAXSAMPLEVALUE: + if (tif->tif_flags & TIFF_PERSAMPLE) + *va_arg(ap, double **) = td->td_smaxsamplevalue; + else + { + /* libtiff historically treats this as a single value. */ + uint16_t i; + double v = td->td_smaxsamplevalue[0]; + for (i = 1; i < td->td_samplesperpixel; ++i) + if (td->td_smaxsamplevalue[i] > v) + v = td->td_smaxsamplevalue[i]; + *va_arg(ap, double *) = v; + } + break; + case TIFFTAG_XRESOLUTION: + *va_arg(ap, float *) = td->td_xresolution; + break; + case TIFFTAG_YRESOLUTION: + *va_arg(ap, float *) = td->td_yresolution; + break; + case TIFFTAG_PLANARCONFIG: + *va_arg(ap, uint16_t *) = td->td_planarconfig; + break; + case TIFFTAG_XPOSITION: + *va_arg(ap, float *) = td->td_xposition; + break; + case TIFFTAG_YPOSITION: + *va_arg(ap, float *) = td->td_yposition; + break; + case TIFFTAG_RESOLUTIONUNIT: + *va_arg(ap, uint16_t *) = td->td_resolutionunit; + break; + case TIFFTAG_PAGENUMBER: + *va_arg(ap, uint16_t *) = td->td_pagenumber[0]; + *va_arg(ap, uint16_t *) = td->td_pagenumber[1]; + break; + case TIFFTAG_HALFTONEHINTS: + *va_arg(ap, uint16_t *) = td->td_halftonehints[0]; + *va_arg(ap, uint16_t *) = td->td_halftonehints[1]; + break; + case TIFFTAG_COLORMAP: + *va_arg(ap, const uint16_t **) = td->td_colormap[0]; + *va_arg(ap, const uint16_t **) = td->td_colormap[1]; + *va_arg(ap, const uint16_t **) = td->td_colormap[2]; + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_TILEOFFSETS: + _TIFFFillStriles(tif); + *va_arg(ap, const uint64_t **) = td->td_stripoffset_p; + if (td->td_stripoffset_p == NULL) + ret_val = 0; + break; + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEBYTECOUNTS: + _TIFFFillStriles(tif); + *va_arg(ap, const uint64_t **) = td->td_stripbytecount_p; + if (td->td_stripbytecount_p == NULL) + ret_val = 0; + break; + case TIFFTAG_MATTEING: + *va_arg(ap, uint16_t *) = + (td->td_extrasamples == 1 && + td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); + break; + case TIFFTAG_EXTRASAMPLES: + *va_arg(ap, uint16_t *) = td->td_extrasamples; + *va_arg(ap, const uint16_t **) = td->td_sampleinfo; + break; + case TIFFTAG_TILEWIDTH: + *va_arg(ap, uint32_t *) = td->td_tilewidth; + break; + case TIFFTAG_TILELENGTH: + *va_arg(ap, uint32_t *) = td->td_tilelength; + break; + case TIFFTAG_TILEDEPTH: + *va_arg(ap, uint32_t *) = td->td_tiledepth; + break; + case TIFFTAG_DATATYPE: + switch (td->td_sampleformat) + { + case SAMPLEFORMAT_UINT: + *va_arg(ap, uint16_t *) = DATATYPE_UINT; + break; + case SAMPLEFORMAT_INT: + *va_arg(ap, uint16_t *) = DATATYPE_INT; + break; + case SAMPLEFORMAT_IEEEFP: + *va_arg(ap, uint16_t *) = DATATYPE_IEEEFP; + break; + case SAMPLEFORMAT_VOID: + *va_arg(ap, uint16_t *) = DATATYPE_VOID; + break; + } + break; + case TIFFTAG_SAMPLEFORMAT: + *va_arg(ap, uint16_t *) = td->td_sampleformat; + break; + case TIFFTAG_IMAGEDEPTH: + *va_arg(ap, uint32_t *) = td->td_imagedepth; + break; + case TIFFTAG_SUBIFD: + *va_arg(ap, uint16_t *) = td->td_nsubifd; + *va_arg(ap, const uint64_t **) = td->td_subifd; + break; + case TIFFTAG_YCBCRPOSITIONING: + *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning; + break; + case TIFFTAG_YCBCRSUBSAMPLING: + *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0]; + *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1]; + break; + case TIFFTAG_TRANSFERFUNCTION: + *va_arg(ap, const uint16_t **) = td->td_transferfunction[0]; + if (td->td_samplesperpixel - td->td_extrasamples > 1) + { + *va_arg(ap, const uint16_t **) = td->td_transferfunction[1]; + *va_arg(ap, const uint16_t **) = td->td_transferfunction[2]; + } + else + { + *va_arg(ap, const uint16_t **) = NULL; + *va_arg(ap, const uint16_t **) = NULL; + } + break; + case TIFFTAG_REFERENCEBLACKWHITE: + *va_arg(ap, const float **) = td->td_refblackwhite; + break; + case TIFFTAG_INKNAMES: + *va_arg(ap, const char **) = td->td_inknames; + break; + case TIFFTAG_NUMBEROFINKS: + *va_arg(ap, uint16_t *) = td->td_numberofinks; + break; + default: + { + int i; + + /* + * This can happen if multiple images are open + * with different codecs which have private + * tags. The global tag information table may + * then have tags that are valid for one file + * but not the other. If the client tries to + * get a tag that is not valid for the image's + * codec then we'll arrive here. + */ + if (fip->field_bit != FIELD_CUSTOM) + { + TIFFErrorExtR(tif, "_TIFFVGetField", + "%s: Invalid %stag \"%s\" " + "(not supported by codec)", + tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", + fip->field_name); + ret_val = 0; + break; + } + + /* + * Do we have a custom value? + */ + ret_val = 0; + for (i = 0; i < td->td_customValueCount; i++) + { + TIFFTagValue *tv = td->td_customValues + i; + + if (tv->info->field_tag != tag) + continue; + + if (fip->field_passcount) + { + if (fip->field_readcount == TIFF_VARIABLE2) + *va_arg(ap, uint32_t *) = (uint32_t)tv->count; + else /* Assume TIFF_VARIABLE */ + *va_arg(ap, uint16_t *) = (uint16_t)tv->count; + *va_arg(ap, const void **) = tv->value; + ret_val = 1; + } + else if (fip->field_tag == TIFFTAG_DOTRANGE && + strcmp(fip->field_name, "DotRange") == 0) + { + /* TODO: This is an evil exception and should not have been + handled this way ... likely best if we move it into + the directory structure with an explicit field in + libtiff 4.1 and assign it a FIELD_ value */ + *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[0]; + *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[1]; + ret_val = 1; + } + else + { + if (fip->field_type == TIFF_ASCII || + fip->field_readcount == TIFF_VARIABLE || + fip->field_readcount == TIFF_VARIABLE2 || + fip->field_readcount == TIFF_SPP || tv->count > 1) + { + *va_arg(ap, void **) = tv->value; + ret_val = 1; + } + else + { + char *val = (char *)tv->value; + assert(tv->count == 1); + switch (fip->field_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + *va_arg(ap, uint8_t *) = *(uint8_t *)val; + ret_val = 1; + break; + case TIFF_SBYTE: + *va_arg(ap, int8_t *) = *(int8_t *)val; + ret_val = 1; + break; + case TIFF_SHORT: + *va_arg(ap, uint16_t *) = *(uint16_t *)val; + ret_val = 1; + break; + case TIFF_SSHORT: + *va_arg(ap, int16_t *) = *(int16_t *)val; + ret_val = 1; + break; + case TIFF_LONG: + case TIFF_IFD: + *va_arg(ap, uint32_t *) = *(uint32_t *)val; + ret_val = 1; + break; + case TIFF_SLONG: + *va_arg(ap, int32_t *) = *(int32_t *)val; + ret_val = 1; + break; + case TIFF_LONG8: + case TIFF_IFD8: + *va_arg(ap, uint64_t *) = *(uint64_t *)val; + ret_val = 1; + break; + case TIFF_SLONG8: + *va_arg(ap, int64_t *) = *(int64_t *)val; + ret_val = 1; + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + { + /*-- Rational2Double: For Rationals evaluate + * "set_field_type" to determine internal + * storage size and return value size. */ + int tv_size = TIFFFieldSetGetSize(fip); + if (tv_size == 8) + { + *va_arg(ap, double *) = *(double *)val; + ret_val = 1; + } + else + { + /*-- default should be tv_size == 4 */ + *va_arg(ap, float *) = *(float *)val; + ret_val = 1; + /*-- ToDo: After Testing, this should be + * removed and tv_size==4 should be set as + * default. */ + if (tv_size != 4) + { + TIFFErrorExtR( + tif, "_TIFFVGetField", + "Rational2Double: .set_field_type " + "in not 4 but %d", + tv_size); + } + } + } + break; + case TIFF_FLOAT: + *va_arg(ap, float *) = *(float *)val; + ret_val = 1; + break; + case TIFF_DOUBLE: + *va_arg(ap, double *) = *(double *)val; + ret_val = 1; + break; + default: + ret_val = 0; + break; + } + } + } + break; + } + } + } + return (ret_val); } /* * Return the value of a field in the * internal directory structure. */ -int -TIFFGetField(TIFF* tif, uint32_t tag, ...) +int TIFFGetField(TIFF *tif, uint32_t tag, ...) { - int status; - va_list ap; + int status; + va_list ap; - va_start(ap, tag); - status = TIFFVGetField(tif, tag, ap); - va_end(ap); - return (status); + va_start(ap, tag); + status = TIFFVGetField(tif, tag, ap); + va_end(ap); + return (status); } /* @@ -1412,74 +1595,75 @@ TIFFGetField(TIFF* tif, uint32_t tag, ...) * for building higher-level interfaces on * top of the library. */ -int -TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap) +int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap) { - const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); - return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ? - (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0); + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) + ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) + : 0); } -#define CleanupField(member) { \ - if (td->member) { \ - _TIFFfreeExt(tif, td->member); \ - td->member = 0; \ - } \ -} +#define CleanupField(member) \ + { \ + if (td->member) \ + { \ + _TIFFfreeExt(tif, td->member); \ + td->member = 0; \ + } \ + } /* * Release storage associated with a directory. */ -void -TIFFFreeDirectory(TIFF* tif) +void TIFFFreeDirectory(TIFF *tif) { - TIFFDirectory *td = &tif->tif_dir; - int i; - - _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS); - CleanupField(td_sminsamplevalue); - CleanupField(td_smaxsamplevalue); - CleanupField(td_colormap[0]); - CleanupField(td_colormap[1]); - CleanupField(td_colormap[2]); - CleanupField(td_sampleinfo); - CleanupField(td_subifd); - CleanupField(td_inknames); - CleanupField(td_refblackwhite); - CleanupField(td_transferfunction[0]); - CleanupField(td_transferfunction[1]); - CleanupField(td_transferfunction[2]); - CleanupField(td_stripoffset_p); - CleanupField(td_stripbytecount_p); - td->td_stripoffsetbyteallocsize = 0; - TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING); - TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING); - - /* Cleanup custom tag values */ - for( i = 0; i < td->td_customValueCount; i++ ) { - if (td->td_customValues[i].value) - _TIFFfreeExt(tif, td->td_customValues[i].value); - } - - td->td_customValueCount = 0; - CleanupField(td_customValues); - - _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); - _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); + TIFFDirectory *td = &tif->tif_dir; + int i; + + _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS); + CleanupField(td_sminsamplevalue); + CleanupField(td_smaxsamplevalue); + CleanupField(td_colormap[0]); + CleanupField(td_colormap[1]); + CleanupField(td_colormap[2]); + CleanupField(td_sampleinfo); + CleanupField(td_subifd); + CleanupField(td_inknames); + CleanupField(td_refblackwhite); + CleanupField(td_transferfunction[0]); + CleanupField(td_transferfunction[1]); + CleanupField(td_transferfunction[2]); + CleanupField(td_stripoffset_p); + CleanupField(td_stripbytecount_p); + td->td_stripoffsetbyteallocsize = 0; + TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING); + TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING); + + /* Cleanup custom tag values */ + for (i = 0; i < td->td_customValueCount; i++) + { + if (td->td_customValues[i].value) + _TIFFfreeExt(tif, td->td_customValues[i].value); + } + + td->td_customValueCount = 0; + CleanupField(td_customValues); + + _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); } #undef CleanupField /* * Client Tag extension support (from Niles Ritter). */ -static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL; +static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL; -TIFFExtendProc -TIFFSetTagExtender(TIFFExtendProc extender) +TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender) { - TIFFExtendProc prev = _TIFFextender; - _TIFFextender = extender; - return (prev); + TIFFExtendProc prev = _TIFFextender; + _TIFFextender = extender; + return (prev); } /* @@ -1489,376 +1673,389 @@ TIFFSetTagExtender(TIFFExtendProc extender) * The newly created directory will not exist on the file till * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called. */ -int -TIFFCreateDirectory(TIFF* tif) +int TIFFCreateDirectory(TIFF *tif) { - TIFFDefaultDirectory(tif); - tif->tif_diroff = 0; - tif->tif_nextdiroff = 0; - tif->tif_curoff = 0; - tif->tif_row = (uint32_t) -1; - tif->tif_curstrip = (uint32_t) -1; - - return 0; + TIFFDefaultDirectory(tif); + tif->tif_diroff = 0; + tif->tif_nextdiroff = 0; + tif->tif_curoff = 0; + tif->tif_row = (uint32_t)-1; + tif->tif_curstrip = (uint32_t)-1; + + return 0; } -int -TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray) +int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray) { - TIFFDefaultDirectory(tif); - - /* - * Reset the field definitions to match the application provided list. - * Hopefully TIFFDefaultDirectory() won't have done anything irreversible - * based on it's assumption this is an image directory. - */ - _TIFFSetupFields(tif, infoarray); - - tif->tif_diroff = 0; - tif->tif_nextdiroff = 0; - tif->tif_curoff = 0; - tif->tif_row = (uint32_t) -1; - tif->tif_curstrip = (uint32_t) -1; - - return 0; + TIFFDefaultDirectory(tif); + + /* + * Reset the field definitions to match the application provided list. + * Hopefully TIFFDefaultDirectory() won't have done anything irreversible + * based on it's assumption this is an image directory. + */ + _TIFFSetupFields(tif, infoarray); + + tif->tif_diroff = 0; + tif->tif_nextdiroff = 0; + tif->tif_curoff = 0; + tif->tif_row = (uint32_t)-1; + tif->tif_curstrip = (uint32_t)-1; + + return 0; } -int -TIFFCreateEXIFDirectory(TIFF* tif) +int TIFFCreateEXIFDirectory(TIFF *tif) { - const TIFFFieldArray* exifFieldArray; - exifFieldArray = _TIFFGetExifFields(); - return TIFFCreateCustomDirectory(tif, exifFieldArray); + const TIFFFieldArray *exifFieldArray; + exifFieldArray = _TIFFGetExifFields(); + return TIFFCreateCustomDirectory(tif, exifFieldArray); } /* - * Creates the EXIF GPS custom directory + * Creates the EXIF GPS custom directory */ -int -TIFFCreateGPSDirectory(TIFF* tif) +int TIFFCreateGPSDirectory(TIFF *tif) { - const TIFFFieldArray* gpsFieldArray; - gpsFieldArray = _TIFFGetGpsFields(); - return TIFFCreateCustomDirectory(tif, gpsFieldArray); + const TIFFFieldArray *gpsFieldArray; + gpsFieldArray = _TIFFGetGpsFields(); + return TIFFCreateCustomDirectory(tif, gpsFieldArray); } /* * Setup a default directory structure. */ -int -TIFFDefaultDirectory(TIFF* tif) +int TIFFDefaultDirectory(TIFF *tif) { - register TIFFDirectory* td = &tif->tif_dir; - const TIFFFieldArray* tiffFieldArray; - - tiffFieldArray = _TIFFGetFields(); - _TIFFSetupFields(tif, tiffFieldArray); - - _TIFFmemset(td, 0, sizeof (*td)); - td->td_fillorder = FILLORDER_MSB2LSB; - td->td_bitspersample = 1; - td->td_threshholding = THRESHHOLD_BILEVEL; - td->td_orientation = ORIENTATION_TOPLEFT; - td->td_samplesperpixel = 1; - td->td_rowsperstrip = (uint32_t) -1; - td->td_tilewidth = 0; - td->td_tilelength = 0; - td->td_tiledepth = 1; + register TIFFDirectory *td = &tif->tif_dir; + const TIFFFieldArray *tiffFieldArray; + + tiffFieldArray = _TIFFGetFields(); + _TIFFSetupFields(tif, tiffFieldArray); + + _TIFFmemset(td, 0, sizeof(*td)); + td->td_fillorder = FILLORDER_MSB2LSB; + td->td_bitspersample = 1; + td->td_threshholding = THRESHHOLD_BILEVEL; + td->td_orientation = ORIENTATION_TOPLEFT; + td->td_samplesperpixel = 1; + td->td_rowsperstrip = (uint32_t)-1; + td->td_tilewidth = 0; + td->td_tilelength = 0; + td->td_tiledepth = 1; #ifdef STRIPBYTECOUNTSORTED_UNUSED - td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ + td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ #endif - td->td_resolutionunit = RESUNIT_INCH; - td->td_sampleformat = SAMPLEFORMAT_UINT; - td->td_imagedepth = 1; - td->td_ycbcrsubsampling[0] = 2; - td->td_ycbcrsubsampling[1] = 2; - td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; - tif->tif_postdecode = _TIFFNoPostDecode; - tif->tif_foundfield = NULL; - tif->tif_tagmethods.vsetfield = _TIFFVSetField; - tif->tif_tagmethods.vgetfield = _TIFFVGetField; - tif->tif_tagmethods.printdir = NULL; - /* additional default values */ - td->td_planarconfig = PLANARCONFIG_CONTIG; - td->td_compression = COMPRESSION_NONE; - td->td_subfiletype = 0; - td->td_minsamplevalue = 0; - /* td_bitspersample=1 is always set in TIFFDefaultDirectory(). - * Therefore, td_maxsamplevalue has to be re-calculated in TIFFGetFieldDefaulted(). */ - td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */ - td->td_extrasamples = 0; - td->td_sampleinfo = NULL; - - /* - * Give client code a chance to install their own - * tag extensions & methods, prior to compression overloads, - * but do some prior cleanup first. (http://trac.osgeo.org/gdal/ticket/5054) - */ - if (tif->tif_nfieldscompat > 0) { - uint32_t i; - - for (i = 0; i < tif->tif_nfieldscompat; i++) { - if (tif->tif_fieldscompat[i].allocated_size) - _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields); - } - _TIFFfreeExt(tif, tif->tif_fieldscompat); - tif->tif_nfieldscompat = 0; - tif->tif_fieldscompat = NULL; - } - if (_TIFFextender) - (*_TIFFextender)(tif); - (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); - /* - * NB: The directory is marked dirty as a result of setting - * up the default compression scheme. However, this really - * isn't correct -- we want TIFF_DIRTYDIRECT to be set only - * if the user does something. We could just do the setup - * by hand, but it seems better to use the normal mechanism - * (i.e. TIFFSetField). - */ - tif->tif_flags &= ~TIFF_DIRTYDIRECT; - - /* - * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 - * we clear the ISTILED flag when setting up a new directory. - * Should we also be clearing stuff like INSUBIFD? - */ - tif->tif_flags &= ~TIFF_ISTILED; - - return (1); + td->td_resolutionunit = RESUNIT_INCH; + td->td_sampleformat = SAMPLEFORMAT_UINT; + td->td_imagedepth = 1; + td->td_ycbcrsubsampling[0] = 2; + td->td_ycbcrsubsampling[1] = 2; + td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; + tif->tif_postdecode = _TIFFNoPostDecode; + tif->tif_foundfield = NULL; + tif->tif_tagmethods.vsetfield = _TIFFVSetField; + tif->tif_tagmethods.vgetfield = _TIFFVGetField; + tif->tif_tagmethods.printdir = NULL; + /* additional default values */ + td->td_planarconfig = PLANARCONFIG_CONTIG; + td->td_compression = COMPRESSION_NONE; + td->td_subfiletype = 0; + td->td_minsamplevalue = 0; + /* td_bitspersample=1 is always set in TIFFDefaultDirectory(). + * Therefore, td_maxsamplevalue has to be re-calculated in + * TIFFGetFieldDefaulted(). */ + td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */ + td->td_extrasamples = 0; + td->td_sampleinfo = NULL; + + /* + * Give client code a chance to install their own + * tag extensions & methods, prior to compression overloads, + * but do some prior cleanup first. + * (http://trac.osgeo.org/gdal/ticket/5054) + */ + if (tif->tif_nfieldscompat > 0) + { + uint32_t i; + + for (i = 0; i < tif->tif_nfieldscompat; i++) + { + if (tif->tif_fieldscompat[i].allocated_size) + _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields); + } + _TIFFfreeExt(tif, tif->tif_fieldscompat); + tif->tif_nfieldscompat = 0; + tif->tif_fieldscompat = NULL; + } + if (_TIFFextender) + (*_TIFFextender)(tif); + (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); + /* + * NB: The directory is marked dirty as a result of setting + * up the default compression scheme. However, this really + * isn't correct -- we want TIFF_DIRTYDIRECT to be set only + * if the user does something. We could just do the setup + * by hand, but it seems better to use the normal mechanism + * (i.e. TIFFSetField). + */ + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + + /* + * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 + * we clear the ISTILED flag when setting up a new directory. + * Should we also be clearing stuff like INSUBIFD? + */ + tif->tif_flags &= ~TIFF_ISTILED; + + return (1); } -static int -TIFFAdvanceDirectory(TIFF* tif, uint64_t* nextdiroff, uint64_t* off, uint16_t* nextdirnum) +static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off, + uint16_t *nextdirnum) { - static const char module[] = "TIFFAdvanceDirectory"; - - /* Add this directory to the directory list, if not already in. */ - if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff)) { - TIFFErrorExtR(tif, module, "Starting directory %"PRIu16" at offset 0x%"PRIx64" (%"PRIu64") might cause an IFD loop", - *nextdirnum, *nextdiroff, *nextdiroff); - *nextdiroff = 0; - *nextdirnum = 0; - return(0); - } - - if (isMapped(tif)) - { - uint64_t poff=*nextdiroff; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - tmsize_t poffa,poffb,poffc,poffd; - uint16_t dircount; - uint32_t nextdir32; - poffa=(tmsize_t)poff; - poffb=poffa+sizeof(uint16_t); - if (((uint64_t)poffa != poff) || (poffb < poffa) || (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size)) - { - TIFFErrorExtR(tif,module,"Error fetching directory count"); - *nextdiroff=0; - return(0); - } - _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16_t)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(&dircount); - poffc=poffb+dircount*12; - poffd=poffc+sizeof(uint32_t); - if ((poffc<poffb) || (poffc<dircount*12) || (poffd<poffc) || (poffd<(tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size)) - { - TIFFErrorExtR(tif,module,"Error fetching directory link"); - return(0); - } - if (off!=NULL) - *off=(uint64_t)poffc; - _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32_t)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&nextdir32); - *nextdiroff=nextdir32; - } - else - { - tmsize_t poffa,poffb,poffc,poffd; - uint64_t dircount64; - uint16_t dircount16; - if( poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t) ) - { - TIFFErrorExtR(tif,module,"Error fetching directory count"); - return(0); - } - poffa=(tmsize_t)poff; - poffb=poffa+sizeof(uint64_t); - if (poffb > tif->tif_size) - { - TIFFErrorExtR(tif,module,"Error fetching directory count"); - return(0); - } - _TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64_t)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>0xFFFF) - { - TIFFErrorExtR(tif,module,"Sanity check on directory count failed"); - return(0); - } - dircount16=(uint16_t)dircount64; - if( poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16*20) - (tmsize_t)sizeof(uint64_t) ) - { - TIFFErrorExtR(tif,module,"Error fetching directory link"); - return(0); - } - poffc=poffb+dircount16*20; - poffd=poffc+sizeof(uint64_t); - if (poffd > tif->tif_size) - { - TIFFErrorExtR(tif,module,"Error fetching directory link"); - return(0); - } - if (off!=NULL) - *off=(uint64_t)poffc; - _TIFFmemcpy(nextdiroff,tif->tif_base+poffc,sizeof(uint64_t)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - else - { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint16_t dircount; - uint32_t nextdir32; - if (!SeekOK(tif, *nextdiroff) || - !ReadOK(tif, &dircount, sizeof (uint16_t))) { - TIFFErrorExtR(tif, module, "%s: Error fetching directory count", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - if (off != NULL) - *off = TIFFSeekFile(tif, - dircount*12, SEEK_CUR); - else - (void) TIFFSeekFile(tif, - dircount*12, SEEK_CUR); - if (!ReadOK(tif, &nextdir32, sizeof (uint32_t))) { - TIFFErrorExtR(tif, module, "%s: Error fetching directory link", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdir32); - *nextdiroff=nextdir32; - } - else - { - uint64_t dircount64; - uint16_t dircount16; - if (!SeekOK(tif, *nextdiroff) || - !ReadOK(tif, &dircount64, sizeof (uint64_t))) { - TIFFErrorExtR(tif, module, "%s: Error fetching directory count", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>0xFFFF) - { - TIFFErrorExtR(tif, module, "Error fetching directory count"); - return(0); - } - dircount16 = (uint16_t)dircount64; - if (off != NULL) - *off = TIFFSeekFile(tif, - dircount16*20, SEEK_CUR); - else - (void) TIFFSeekFile(tif, - dircount16*20, SEEK_CUR); - if (!ReadOK(tif, nextdiroff, sizeof (uint64_t))) { - TIFFErrorExtR(tif, module, "%s: Error fetching directory link", - tif->tif_name); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - if (*nextdiroff != 0) { - (*nextdirnum)++; - /* Check next directory for IFD looping and if so, set it as last directory. */ - if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff)) { - TIFFWarningExtR(tif, module, "the next directory %"PRIu16" at offset 0x%"PRIx64" (%"PRIu64") might be an IFD loop. Treating directory %d as last directory", - *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1); - *nextdiroff = 0; - (*nextdirnum)--; - } - } - return (1); + static const char module[] = "TIFFAdvanceDirectory"; + + /* Add this directory to the directory list, if not already in. */ + if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff)) + { + TIFFErrorExtR(tif, module, + "Starting directory %" PRIu16 " at offset 0x%" PRIx64 + " (%" PRIu64 ") might cause an IFD loop", + *nextdirnum, *nextdiroff, *nextdiroff); + *nextdiroff = 0; + *nextdirnum = 0; + return (0); + } + + if (isMapped(tif)) + { + uint64_t poff = *nextdiroff; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + tmsize_t poffa, poffb, poffc, poffd; + uint16_t dircount; + uint32_t nextdir32; + poffa = (tmsize_t)poff; + poffb = poffa + sizeof(uint16_t); + if (((uint64_t)poffa != poff) || (poffb < poffa) || + (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size)) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + *nextdiroff = 0; + return (0); + } + _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + poffc = poffb + dircount * 12; + poffd = poffc + sizeof(uint32_t); + if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) || + (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (off != NULL) + *off = (uint64_t)poffc; + _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir32); + *nextdiroff = nextdir32; + } + else + { + tmsize_t poffa, poffb, poffc, poffd; + uint64_t dircount64; + uint16_t dircount16; + if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t)) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + return (0); + } + poffa = (tmsize_t)poff; + poffb = poffa + sizeof(uint64_t); + if (poffb > tif->tif_size) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + return (0); + } + _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 0xFFFF) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed"); + return (0); + } + dircount16 = (uint16_t)dircount64; + if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) - + (tmsize_t)sizeof(uint64_t)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + poffc = poffb + dircount16 * 20; + poffd = poffc + sizeof(uint64_t); + if (poffd > tif->tif_size) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (off != NULL) + *off = (uint64_t)poffc; + _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } + else + { + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint16_t dircount; + uint32_t nextdir32; + if (!SeekOK(tif, *nextdiroff) || + !ReadOK(tif, &dircount, sizeof(uint16_t))) + { + TIFFErrorExtR(tif, module, "%s: Error fetching directory count", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + if (off != NULL) + *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR); + else + (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR); + if (!ReadOK(tif, &nextdir32, sizeof(uint32_t))) + { + TIFFErrorExtR(tif, module, "%s: Error fetching directory link", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir32); + *nextdiroff = nextdir32; + } + else + { + uint64_t dircount64; + uint16_t dircount16; + if (!SeekOK(tif, *nextdiroff) || + !ReadOK(tif, &dircount64, sizeof(uint64_t))) + { + TIFFErrorExtR(tif, module, "%s: Error fetching directory count", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 0xFFFF) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + return (0); + } + dircount16 = (uint16_t)dircount64; + if (off != NULL) + *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR); + else + (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR); + if (!ReadOK(tif, nextdiroff, sizeof(uint64_t))) + { + TIFFErrorExtR(tif, module, "%s: Error fetching directory link", + tif->tif_name); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } + if (*nextdiroff != 0) + { + (*nextdirnum)++; + /* Check next directory for IFD looping and if so, set it as last + * directory. */ + if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff)) + { + TIFFWarningExtR( + tif, module, + "the next directory %" PRIu16 " at offset 0x%" PRIx64 + " (%" PRIu64 ") might be an IFD loop. Treating directory %d as " + "last directory", + *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1); + *nextdiroff = 0; + (*nextdirnum)--; + } + } + return (1); } /* * Count the number of directories in a file. */ -uint16_t -TIFFNumberOfDirectories(TIFF* tif) +uint16_t TIFFNumberOfDirectories(TIFF *tif) { - static const char module[] = "TIFFNumberOfDirectories"; - uint64_t nextdiroff; - uint16_t nextdirnum; - uint16_t n; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - nextdiroff = tif->tif_header.classic.tiff_diroff; - else - nextdiroff = tif->tif_header.big.tiff_diroff; - nextdirnum = 0; - n = 0; - while (nextdiroff != 0 && TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum)) + static const char module[] = "TIFFNumberOfDirectories"; + uint64_t nextdiroff; + uint16_t nextdirnum; + uint16_t n; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + nextdiroff = tif->tif_header.classic.tiff_diroff; + else + nextdiroff = tif->tif_header.big.tiff_diroff; + nextdirnum = 0; + n = 0; + while (nextdiroff != 0 && + TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum)) + { + if (n != 65535) { - if (n != 65535) { - ++n; - } - else - { - TIFFErrorExtR(tif, module, - "Directory count exceeded 65535 limit," - " giving up on counting."); - return (65535); - } + ++n; + } + else + { + TIFFErrorExtR(tif, module, + "Directory count exceeded 65535 limit," + " giving up on counting."); + return (65535); } - return (n); + } + return (n); } /* * Set the n-th directory as the current directory. * NB: Directories are numbered starting at 0. */ -int -TIFFSetDirectory(TIFF* tif, uint16_t dirn) +int TIFFSetDirectory(TIFF *tif, uint16_t dirn) { - uint64_t nextdiroff; - uint16_t nextdirnum; - uint16_t n; - - if (!(tif->tif_flags&TIFF_BIGTIFF)) - nextdiroff = tif->tif_header.classic.tiff_diroff; - else - nextdiroff = tif->tif_header.big.tiff_diroff; - nextdirnum = 0; - for (n = dirn; n > 0 && nextdiroff != 0; n--) - if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum)) - return (0); - /* If the n-th directory could not be reached (does not exist), - * return here without touching anything further. */ - if (nextdiroff == 0 || n > 0) - return (0); - - tif->tif_nextdiroff = nextdiroff; - /* - * Set curdir to the actual directory index. The - * -1 is because TIFFReadDirectory will increment - * tif_curdir after successfully reading the directory. - */ - tif->tif_curdir = (dirn - n) - 1; - return (TIFFReadDirectory(tif)); + uint64_t nextdiroff; + uint16_t nextdirnum; + uint16_t n; + + if (!(tif->tif_flags & TIFF_BIGTIFF)) + nextdiroff = tif->tif_header.classic.tiff_diroff; + else + nextdiroff = tif->tif_header.big.tiff_diroff; + nextdirnum = 0; + for (n = dirn; n > 0 && nextdiroff != 0; n--) + if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum)) + return (0); + /* If the n-th directory could not be reached (does not exist), + * return here without touching anything further. */ + if (nextdiroff == 0 || n > 0) + return (0); + + tif->tif_nextdiroff = nextdiroff; + /* + * Set curdir to the actual directory index. The + * -1 is because TIFFReadDirectory will increment + * tif_curdir after successfully reading the directory. + */ + tif->tif_curdir = (dirn - n) - 1; + return (TIFFReadDirectory(tif)); } /* @@ -1867,166 +2064,173 @@ TIFFSetDirectory(TIFF* tif, uint16_t dirn) * is used mainly to access directories linked with * the SubIFD tag (e.g. thumbnail images). */ -int -TIFFSetSubDirectory(TIFF* tif, uint64_t diroff) +int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff) { - /* Match nextdiroff and curdir for consistent IFD-loop checking. - * Only with TIFFSetSubDirectory() the IFD list can be corrupted with invalid offsets - * within the main IFD tree. - * In the case of several subIFDs of a main image, - * there are two possibilities that are not even mutually exclusive. - * a.) The subIFD tag contains an array with all offsets of the subIFDs. - * b.) The SubIFDs are concatenated with their NextIFD parameters. - * (refer to https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.) - */ - int retval; - uint16_t curdir = 0; - int8_t probablySubIFD = 0; - if (diroff == 0) { - /* Special case to invalidate the tif_lastdiroff member. */ - tif->tif_curdir = 65535; - } else { - if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir)) { - /* Non-existing offsets might point to a SubIFD or invalid IFD.*/ - probablySubIFD = 1; - } - /* -1 because TIFFReadDirectory() will increment tif_curdir. */ - tif->tif_curdir = curdir - 1; - } - - tif->tif_nextdiroff = diroff; - retval = TIFFReadDirectory(tif); - /* If failed, curdir was not incremented in TIFFReadDirectory(), so set it back. */ - if (!retval )tif->tif_curdir++; - if (retval && probablySubIFD) { - /* Reset IFD list to start new one for SubIFD chain and also start SubIFD chain with tif_curdir=0. */ - tif->tif_dirnumber = 0; - tif->tif_curdir = 0; /* first directory of new chain */ - /* add this offset to new IFD list */ - _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff); - } - return (retval); + /* Match nextdiroff and curdir for consistent IFD-loop checking. + * Only with TIFFSetSubDirectory() the IFD list can be corrupted with + * invalid offsets within the main IFD tree. In the case of several subIFDs + * of a main image, there are two possibilities that are not even mutually + * exclusive. a.) The subIFD tag contains an array with all offsets of the + * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters. + * (refer to + * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.) + */ + int retval; + uint16_t curdir = 0; + int8_t probablySubIFD = 0; + if (diroff == 0) + { + /* Special case to invalidate the tif_lastdiroff member. */ + tif->tif_curdir = 65535; + } + else + { + if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir)) + { + /* Non-existing offsets might point to a SubIFD or invalid IFD.*/ + probablySubIFD = 1; + } + /* -1 because TIFFReadDirectory() will increment tif_curdir. */ + tif->tif_curdir = curdir - 1; + } + + tif->tif_nextdiroff = diroff; + retval = TIFFReadDirectory(tif); + /* If failed, curdir was not incremented in TIFFReadDirectory(), so set it + * back. */ + if (!retval) + tif->tif_curdir++; + if (retval && probablySubIFD) + { + /* Reset IFD list to start new one for SubIFD chain and also start + * SubIFD chain with tif_curdir=0. */ + tif->tif_dirnumber = 0; + tif->tif_curdir = 0; /* first directory of new chain */ + /* add this offset to new IFD list */ + _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff); + } + return (retval); } /* * Return file offset of the current directory. */ -uint64_t -TIFFCurrentDirOffset(TIFF* tif) -{ - return (tif->tif_diroff); -} +uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); } /* * Return an indication of whether or not we are * at the last directory in the file. */ -int -TIFFLastDirectory(TIFF* tif) -{ - return (tif->tif_nextdiroff == 0); -} +int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); } /* * Unlink the specified directory from the directory chain. - * Note: First directory starts with number dirn=1. - * This is different to TIFFSetDirectory() where the first directory starts with zero. + * Note: First directory starts with number dirn=1. + * This is different to TIFFSetDirectory() where the first directory starts with + * zero. */ -int -TIFFUnlinkDirectory(TIFF* tif, uint16_t dirn) +int TIFFUnlinkDirectory(TIFF *tif, uint16_t dirn) { - static const char module[] = "TIFFUnlinkDirectory"; - uint64_t nextdir; - uint16_t nextdirnum; - uint64_t off; - uint16_t n; - - if (tif->tif_mode == O_RDONLY) { - TIFFErrorExtR(tif, module, - "Can not unlink directory in read-only file"); - return (0); - } - /* - * Go to the directory before the one we want - * to unlink and nab the offset of the link - * field we'll need to patch. - */ - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - nextdir = tif->tif_header.classic.tiff_diroff; - off = 4; - } - else - { - nextdir = tif->tif_header.big.tiff_diroff; - off = 8; - } - nextdirnum = 0; /* First directory is dirn=0 */ - - for (n = dirn-1; n > 0; n--) { - if (nextdir == 0) { - TIFFErrorExtR(tif, module, "Directory %"PRIu16" does not exist", dirn); - return (0); - } - if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum)) - return (0); - } - /* - * Advance to the directory to be unlinked and fetch - * the offset of the directory that follows. - */ - if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum)) - return (0); - /* - * Go back and patch the link field of the preceding - * directory to point to the offset of the directory - * that follows. - */ - (void) TIFFSeekFile(tif, off, SEEK_SET); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32_t nextdir32; - nextdir32=(uint32_t)nextdir; - assert((uint64_t)nextdir32 == nextdir); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextdir32); - if (!WriteOK(tif, &nextdir32, sizeof (uint32_t))) { - TIFFErrorExtR(tif, module, "Error writing directory link"); - return (0); - } - } - else - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&nextdir); - if (!WriteOK(tif, &nextdir, sizeof (uint64_t))) { - TIFFErrorExtR(tif, module, "Error writing directory link"); - return (0); - } - } - /* - * Leave directory state setup safely. We don't have - * facilities for doing inserting and removing directories, - * so it's safest to just invalidate everything. This - * means that the caller can only append to the directory - * chain. - */ - (*tif->tif_cleanup)(tif); - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawcc = 0; - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = 0; - } - tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE); - TIFFFreeDirectory(tif); - TIFFDefaultDirectory(tif); - tif->tif_diroff = 0; /* force link on next write */ - tif->tif_nextdiroff = 0; /* next write must be at end */ - tif->tif_lastdiroff = 0; /* will be updated on next link */ - tif->tif_curoff = 0; - tif->tif_row = (uint32_t) -1; - tif->tif_curstrip = (uint32_t) -1; - return (1); + static const char module[] = "TIFFUnlinkDirectory"; + uint64_t nextdir; + uint16_t nextdirnum; + uint64_t off; + uint16_t n; + + if (tif->tif_mode == O_RDONLY) + { + TIFFErrorExtR(tif, module, + "Can not unlink directory in read-only file"); + return (0); + } + /* + * Go to the directory before the one we want + * to unlink and nab the offset of the link + * field we'll need to patch. + */ + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + nextdir = tif->tif_header.classic.tiff_diroff; + off = 4; + } + else + { + nextdir = tif->tif_header.big.tiff_diroff; + off = 8; + } + nextdirnum = 0; /* First directory is dirn=0 */ + + for (n = dirn - 1; n > 0; n--) + { + if (nextdir == 0) + { + TIFFErrorExtR(tif, module, "Directory %" PRIu16 " does not exist", + dirn); + return (0); + } + if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum)) + return (0); + } + /* + * Advance to the directory to be unlinked and fetch + * the offset of the directory that follows. + */ + if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum)) + return (0); + /* + * Go back and patch the link field of the preceding + * directory to point to the offset of the directory + * that follows. + */ + (void)TIFFSeekFile(tif, off, SEEK_SET); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t nextdir32; + nextdir32 = (uint32_t)nextdir; + assert((uint64_t)nextdir32 == nextdir); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdir32); + if (!WriteOK(tif, &nextdir32, sizeof(uint32_t))) + { + TIFFErrorExtR(tif, module, "Error writing directory link"); + return (0); + } + } + else + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextdir); + if (!WriteOK(tif, &nextdir, sizeof(uint64_t))) + { + TIFFErrorExtR(tif, module, "Error writing directory link"); + return (0); + } + } + /* + * Leave directory state setup safely. We don't have + * facilities for doing inserting and removing directories, + * so it's safest to just invalidate everything. This + * means that the caller can only append to the directory + * chain. + */ + (*tif->tif_cleanup)(tif); + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + { + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawcc = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; + } + tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE | + TIFF_BUF4WRITE); + TIFFFreeDirectory(tif); + TIFFDefaultDirectory(tif); + tif->tif_diroff = 0; /* force link on next write */ + tif->tif_nextdiroff = 0; /* next write must be at end */ + tif->tif_lastdiroff = 0; /* will be updated on next link */ + tif->tif_curoff = 0; + tif->tif_row = (uint32_t)-1; + tif->tif_curstrip = (uint32_t)-1; + return (1); } diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h index 514215a2..3c5fd282 100644 --- a/libtiff/tif_dir.h +++ b/libtiff/tif_dir.h @@ -2,28 +2,28 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _TIFFDIR_ -#define _TIFFDIR_ +#define _TIFFDIR_ #include "tiff.h" #include "tiffio.h" @@ -32,10 +32,11 @@ * ``Library-private'' Directory-related Definitions. */ -typedef struct { - const TIFFField *info; - int count; - void *value; +typedef struct +{ + const TIFFField *info; + int count; + void *value; } TIFFTagValue; /* @@ -49,80 +50,91 @@ typedef struct { * BigTIFF, then it is placed in the offset field to save space. If so, * it is left-justified in the offset field. */ -typedef struct { - uint16_t tdir_tag; /* see below */ - uint16_t tdir_type; /* data type; see below */ - uint64_t tdir_count; /* number of items; length in spec */ - union { - uint16_t toff_short; - uint32_t toff_long; - uint64_t toff_long8; - } tdir_offset; /* either offset or the data itself if fits */ - uint8_t tdir_ignore; /* flag status to ignore tag when parsing tags in tif_dirread.c */ +typedef struct +{ + uint16_t tdir_tag; /* see below */ + uint16_t tdir_type; /* data type; see below */ + uint64_t tdir_count; /* number of items; length in spec */ + union + { + uint16_t toff_short; + uint32_t toff_long; + uint64_t toff_long8; + } tdir_offset; /* either offset or the data itself if fits */ + uint8_t tdir_ignore; /* flag status to ignore tag when parsing tags in + tif_dirread.c */ } TIFFDirEntry; /* * Internal format of a TIFF directory entry. */ -typedef struct { +typedef struct +{ #define FIELD_SETLONGS 4 - /* bit vector of fields that are set */ - unsigned long td_fieldsset[FIELD_SETLONGS]; + /* bit vector of fields that are set */ + unsigned long td_fieldsset[FIELD_SETLONGS]; - uint32_t td_imagewidth, td_imagelength, td_imagedepth; - uint32_t td_tilewidth, td_tilelength, td_tiledepth; - uint32_t td_subfiletype; - uint16_t td_bitspersample; - uint16_t td_sampleformat; - uint16_t td_compression; - uint16_t td_photometric; - uint16_t td_threshholding; - uint16_t td_fillorder; - uint16_t td_orientation; - uint16_t td_samplesperpixel; - uint32_t td_rowsperstrip; - uint16_t td_minsamplevalue, td_maxsamplevalue; - double* td_sminsamplevalue; - double* td_smaxsamplevalue; - float td_xresolution, td_yresolution; - uint16_t td_resolutionunit; - uint16_t td_planarconfig; - float td_xposition, td_yposition; - uint16_t td_pagenumber[2]; - uint16_t* td_colormap[3]; - uint16_t td_halftonehints[2]; - uint16_t td_extrasamples; - uint16_t* td_sampleinfo; - /* even though the name is misleading, td_stripsperimage is the number - * of striles (=strips or tiles) per plane, and td_nstrips the total - * number of striles */ - uint32_t td_stripsperimage; - uint32_t td_nstrips; /* size of offset & bytecount arrays */ - uint64_t* td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */ - uint64_t* td_stripbytecount_p; /* should be accessed with TIFFGetStrileByteCount */ - uint32_t td_stripoffsetbyteallocsize; /* number of elements currently allocated for td_stripoffset/td_stripbytecount. Only used if TIFF_LAZYSTRILELOAD is set */ + uint32_t td_imagewidth, td_imagelength, td_imagedepth; + uint32_t td_tilewidth, td_tilelength, td_tiledepth; + uint32_t td_subfiletype; + uint16_t td_bitspersample; + uint16_t td_sampleformat; + uint16_t td_compression; + uint16_t td_photometric; + uint16_t td_threshholding; + uint16_t td_fillorder; + uint16_t td_orientation; + uint16_t td_samplesperpixel; + uint32_t td_rowsperstrip; + uint16_t td_minsamplevalue, td_maxsamplevalue; + double *td_sminsamplevalue; + double *td_smaxsamplevalue; + float td_xresolution, td_yresolution; + uint16_t td_resolutionunit; + uint16_t td_planarconfig; + float td_xposition, td_yposition; + uint16_t td_pagenumber[2]; + uint16_t *td_colormap[3]; + uint16_t td_halftonehints[2]; + uint16_t td_extrasamples; + uint16_t *td_sampleinfo; + /* even though the name is misleading, td_stripsperimage is the number + * of striles (=strips or tiles) per plane, and td_nstrips the total + * number of striles */ + uint32_t td_stripsperimage; + uint32_t td_nstrips; /* size of offset & bytecount arrays */ + uint64_t + *td_stripoffset_p; /* should be accessed with TIFFGetStrileOffset */ + uint64_t *td_stripbytecount_p; /* should be accessed with + TIFFGetStrileByteCount */ + uint32_t + td_stripoffsetbyteallocsize; /* number of elements currently allocated + for td_stripoffset/td_stripbytecount. + Only used if TIFF_LAZYSTRILELOAD is set + */ #ifdef STRIPBYTECOUNTSORTED_UNUSED - int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */ + int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */ #endif - TIFFDirEntry td_stripoffset_entry; /* for deferred loading */ - TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */ - uint16_t td_nsubifd; - uint64_t* td_subifd; - /* YCbCr parameters */ - uint16_t td_ycbcrsubsampling[2]; - uint16_t td_ycbcrpositioning; - /* Colorimetry parameters */ - uint16_t* td_transferfunction[3]; - float* td_refblackwhite; - /* CMYK parameters */ - int td_inknameslen; - char* td_inknames; - uint16_t td_numberofinks; /* number of inks in InkNames string */ + TIFFDirEntry td_stripoffset_entry; /* for deferred loading */ + TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */ + uint16_t td_nsubifd; + uint64_t *td_subifd; + /* YCbCr parameters */ + uint16_t td_ycbcrsubsampling[2]; + uint16_t td_ycbcrpositioning; + /* Colorimetry parameters */ + uint16_t *td_transferfunction[3]; + float *td_refblackwhite; + /* CMYK parameters */ + int td_inknameslen; + char *td_inknames; + uint16_t td_numberofinks; /* number of inks in InkNames string */ - int td_customValueCount; - TIFFTagValue *td_customValues; + int td_customValueCount; + TIFFTagValue *td_customValues; - unsigned char td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */ + unsigned char + td_deferstrilearraywriting; /* see TIFFDeferStrileArrayWriting() */ } TIFFDirectory; /* @@ -136,50 +148,49 @@ typedef struct { * Note that a bit *is* allocated for ignored tags; this is understood by the * directory reading logic which uses this fact to avoid special-case handling */ -#define FIELD_IGNORE 0 +#define FIELD_IGNORE 0 /* multi-item fields */ -#define FIELD_IMAGEDIMENSIONS 1 -#define FIELD_TILEDIMENSIONS 2 -#define FIELD_RESOLUTION 3 -#define FIELD_POSITION 4 +#define FIELD_IMAGEDIMENSIONS 1 +#define FIELD_TILEDIMENSIONS 2 +#define FIELD_RESOLUTION 3 +#define FIELD_POSITION 4 /* single-item fields */ -#define FIELD_SUBFILETYPE 5 -#define FIELD_BITSPERSAMPLE 6 -#define FIELD_COMPRESSION 7 -#define FIELD_PHOTOMETRIC 8 -#define FIELD_THRESHHOLDING 9 -#define FIELD_FILLORDER 10 -#define FIELD_ORIENTATION 15 -#define FIELD_SAMPLESPERPIXEL 16 -#define FIELD_ROWSPERSTRIP 17 -#define FIELD_MINSAMPLEVALUE 18 -#define FIELD_MAXSAMPLEVALUE 19 -#define FIELD_PLANARCONFIG 20 -#define FIELD_RESOLUTIONUNIT 22 -#define FIELD_PAGENUMBER 23 -#define FIELD_STRIPBYTECOUNTS 24 -#define FIELD_STRIPOFFSETS 25 -#define FIELD_COLORMAP 26 -#define FIELD_EXTRASAMPLES 31 -#define FIELD_SAMPLEFORMAT 32 -#define FIELD_SMINSAMPLEVALUE 33 -#define FIELD_SMAXSAMPLEVALUE 34 -#define FIELD_IMAGEDEPTH 35 -#define FIELD_TILEDEPTH 36 -#define FIELD_HALFTONEHINTS 37 -#define FIELD_YCBCRSUBSAMPLING 39 -#define FIELD_YCBCRPOSITIONING 40 -#define FIELD_REFBLACKWHITE 41 -#define FIELD_TRANSFERFUNCTION 44 -#define FIELD_INKNAMES 46 -#define FIELD_SUBIFD 49 -#define FIELD_NUMBEROFINKS 50 +#define FIELD_SUBFILETYPE 5 +#define FIELD_BITSPERSAMPLE 6 +#define FIELD_COMPRESSION 7 +#define FIELD_PHOTOMETRIC 8 +#define FIELD_THRESHHOLDING 9 +#define FIELD_FILLORDER 10 +#define FIELD_ORIENTATION 15 +#define FIELD_SAMPLESPERPIXEL 16 +#define FIELD_ROWSPERSTRIP 17 +#define FIELD_MINSAMPLEVALUE 18 +#define FIELD_MAXSAMPLEVALUE 19 +#define FIELD_PLANARCONFIG 20 +#define FIELD_RESOLUTIONUNIT 22 +#define FIELD_PAGENUMBER 23 +#define FIELD_STRIPBYTECOUNTS 24 +#define FIELD_STRIPOFFSETS 25 +#define FIELD_COLORMAP 26 +#define FIELD_EXTRASAMPLES 31 +#define FIELD_SAMPLEFORMAT 32 +#define FIELD_SMINSAMPLEVALUE 33 +#define FIELD_SMAXSAMPLEVALUE 34 +#define FIELD_IMAGEDEPTH 35 +#define FIELD_TILEDEPTH 36 +#define FIELD_HALFTONEHINTS 37 +#define FIELD_YCBCRSUBSAMPLING 39 +#define FIELD_YCBCRPOSITIONING 40 +#define FIELD_REFBLACKWHITE 41 +#define FIELD_TRANSFERFUNCTION 44 +#define FIELD_INKNAMES 46 +#define FIELD_SUBIFD 49 +#define FIELD_NUMBEROFINKS 50 /* FIELD_CUSTOM (see tiffio.h) 65 */ /* end of support for well-known tags; codec-private tags follow */ -#define FIELD_CODEC 66 /* base of codec-private tags */ - +#define FIELD_CODEC 66 /* base of codec-private tags */ /* * Pseudo-tags don't normally need field bits since they are not written to an @@ -189,121 +200,135 @@ typedef struct { * or ``unset'' then it can do using internal state flags without polluting * the field bit space defined for real tags. */ -#define FIELD_PSEUDO 0 +#define FIELD_PSEUDO 0 -#define FIELD_LAST (32*FIELD_SETLONGS-1) +#define FIELD_LAST (32 * FIELD_SETLONGS - 1) -#define BITn(n) (((unsigned long)1L)<<((n)&0x1f)) -#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n)/32]) -#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field)) -#define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field)) -#define TIFFClrFieldBit(tif, field) (BITFIELDn(tif, field) &= ~BITn(field)) +#define BITn(n) (((unsigned long)1L) << ((n)&0x1f)) +#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n) / 32]) +#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field)) +#define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field)) +#define TIFFClrFieldBit(tif, field) (BITFIELDn(tif, field) &= ~BITn(field)) -#define FieldSet(fields, f) (fields[(f)/32] & BITn(f)) -#define ResetFieldBit(fields, f) (fields[(f)/32] &= ~BITn(f)) +#define FieldSet(fields, f) (fields[(f) / 32] & BITn(f)) +#define ResetFieldBit(fields, f) (fields[(f) / 32] &= ~BITn(f)) -typedef enum { - TIFF_SETGET_UNDEFINED = 0, - TIFF_SETGET_ASCII = 1, - TIFF_SETGET_UINT8 = 2, - TIFF_SETGET_SINT8 = 3, - TIFF_SETGET_UINT16 = 4, - TIFF_SETGET_SINT16 = 5, - TIFF_SETGET_UINT32 = 6, - TIFF_SETGET_SINT32 = 7, - TIFF_SETGET_UINT64 = 8, - TIFF_SETGET_SINT64 = 9, - TIFF_SETGET_FLOAT = 10, - TIFF_SETGET_DOUBLE = 11, - TIFF_SETGET_IFD8 = 12, - TIFF_SETGET_INT = 13, - TIFF_SETGET_UINT16_PAIR = 14, - TIFF_SETGET_C0_ASCII = 15, - TIFF_SETGET_C0_UINT8 = 16, - TIFF_SETGET_C0_SINT8 = 17, - TIFF_SETGET_C0_UINT16 = 18, - TIFF_SETGET_C0_SINT16 = 19, - TIFF_SETGET_C0_UINT32 = 20, - TIFF_SETGET_C0_SINT32 = 21, - TIFF_SETGET_C0_UINT64 = 22, - TIFF_SETGET_C0_SINT64 = 23, - TIFF_SETGET_C0_FLOAT = 24, - TIFF_SETGET_C0_DOUBLE = 25, - TIFF_SETGET_C0_IFD8 = 26, - TIFF_SETGET_C16_ASCII = 27, - TIFF_SETGET_C16_UINT8 = 28, - TIFF_SETGET_C16_SINT8 = 29, - TIFF_SETGET_C16_UINT16 = 30, - TIFF_SETGET_C16_SINT16 = 31, - TIFF_SETGET_C16_UINT32 = 32, - TIFF_SETGET_C16_SINT32 = 33, - TIFF_SETGET_C16_UINT64 = 34, - TIFF_SETGET_C16_SINT64 = 35, - TIFF_SETGET_C16_FLOAT = 36, - TIFF_SETGET_C16_DOUBLE = 37, - TIFF_SETGET_C16_IFD8 = 38, - TIFF_SETGET_C32_ASCII = 39, - TIFF_SETGET_C32_UINT8 = 40, - TIFF_SETGET_C32_SINT8 = 41, - TIFF_SETGET_C32_UINT16 = 42, - TIFF_SETGET_C32_SINT16 = 43, - TIFF_SETGET_C32_UINT32 = 44, - TIFF_SETGET_C32_SINT32 = 45, - TIFF_SETGET_C32_UINT64 = 46, - TIFF_SETGET_C32_SINT64 = 47, - TIFF_SETGET_C32_FLOAT = 48, - TIFF_SETGET_C32_DOUBLE = 49, - TIFF_SETGET_C32_IFD8 = 50, - TIFF_SETGET_OTHER = 51 +typedef enum +{ + TIFF_SETGET_UNDEFINED = 0, + TIFF_SETGET_ASCII = 1, + TIFF_SETGET_UINT8 = 2, + TIFF_SETGET_SINT8 = 3, + TIFF_SETGET_UINT16 = 4, + TIFF_SETGET_SINT16 = 5, + TIFF_SETGET_UINT32 = 6, + TIFF_SETGET_SINT32 = 7, + TIFF_SETGET_UINT64 = 8, + TIFF_SETGET_SINT64 = 9, + TIFF_SETGET_FLOAT = 10, + TIFF_SETGET_DOUBLE = 11, + TIFF_SETGET_IFD8 = 12, + TIFF_SETGET_INT = 13, + TIFF_SETGET_UINT16_PAIR = 14, + TIFF_SETGET_C0_ASCII = 15, + TIFF_SETGET_C0_UINT8 = 16, + TIFF_SETGET_C0_SINT8 = 17, + TIFF_SETGET_C0_UINT16 = 18, + TIFF_SETGET_C0_SINT16 = 19, + TIFF_SETGET_C0_UINT32 = 20, + TIFF_SETGET_C0_SINT32 = 21, + TIFF_SETGET_C0_UINT64 = 22, + TIFF_SETGET_C0_SINT64 = 23, + TIFF_SETGET_C0_FLOAT = 24, + TIFF_SETGET_C0_DOUBLE = 25, + TIFF_SETGET_C0_IFD8 = 26, + TIFF_SETGET_C16_ASCII = 27, + TIFF_SETGET_C16_UINT8 = 28, + TIFF_SETGET_C16_SINT8 = 29, + TIFF_SETGET_C16_UINT16 = 30, + TIFF_SETGET_C16_SINT16 = 31, + TIFF_SETGET_C16_UINT32 = 32, + TIFF_SETGET_C16_SINT32 = 33, + TIFF_SETGET_C16_UINT64 = 34, + TIFF_SETGET_C16_SINT64 = 35, + TIFF_SETGET_C16_FLOAT = 36, + TIFF_SETGET_C16_DOUBLE = 37, + TIFF_SETGET_C16_IFD8 = 38, + TIFF_SETGET_C32_ASCII = 39, + TIFF_SETGET_C32_UINT8 = 40, + TIFF_SETGET_C32_SINT8 = 41, + TIFF_SETGET_C32_UINT16 = 42, + TIFF_SETGET_C32_SINT16 = 43, + TIFF_SETGET_C32_UINT32 = 44, + TIFF_SETGET_C32_SINT32 = 45, + TIFF_SETGET_C32_UINT64 = 46, + TIFF_SETGET_C32_SINT64 = 47, + TIFF_SETGET_C32_FLOAT = 48, + TIFF_SETGET_C32_DOUBLE = 49, + TIFF_SETGET_C32_IFD8 = 50, + TIFF_SETGET_OTHER = 51 } TIFFSetGetFieldType; #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -extern const TIFFFieldArray* _TIFFGetFields(void); -extern const TIFFFieldArray* _TIFFGetExifFields(void); -extern const TIFFFieldArray* _TIFFGetGpsFields(void); -extern void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* infoarray); -extern void _TIFFPrintFieldInfo(TIFF*, FILE*); + extern const TIFFFieldArray *_TIFFGetFields(void); + extern const TIFFFieldArray *_TIFFGetExifFields(void); + extern const TIFFFieldArray *_TIFFGetGpsFields(void); + extern void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *infoarray); + extern void _TIFFPrintFieldInfo(TIFF *, FILE *); -extern int _TIFFFillStriles(TIFF*); + extern int _TIFFFillStriles(TIFF *); -typedef enum { - tfiatImage, - tfiatExif, - tfiatGps, /* EXIF-GPS fields array type */ - tfiatOther -} TIFFFieldArrayType; + typedef enum + { + tfiatImage, + tfiatExif, + tfiatGps, /* EXIF-GPS fields array type */ + tfiatOther + } TIFFFieldArrayType; -struct _TIFFFieldArray { - TIFFFieldArrayType type; /* array type, will be used to determine if IFD is image and such */ - uint32_t allocated_size; /* 0 if array is constant, other if modified by future definition extension support */ - uint32_t count; /* number of elements in fields array */ - TIFFField* fields; /* actual field info */ -}; + struct _TIFFFieldArray + { + TIFFFieldArrayType type; /* array type, will be used to determine if IFD + is image and such */ + uint32_t allocated_size; /* 0 if array is constant, other if modified by + future definition extension support */ + uint32_t count; /* number of elements in fields array */ + TIFFField *fields; /* actual field info */ + }; -struct _TIFFField { - uint32_t field_tag; /* field's tag */ - short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ - short field_writecount; /* write count/TIFF_VARIABLE */ - TIFFDataType field_type; /* type of associated data */ - uint32_t field_anonymous; /* if true, this is a unknown / anonymous tag */ - TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField */ - TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */ - unsigned short field_bit; /* bit in fieldsset bit vector */ - unsigned char field_oktochange; /* if true, can change while writing */ - unsigned char field_passcount; /* if true, pass dir count on set */ - char* field_name; /* ASCII name */ - TIFFFieldArray* field_subfields; /* if field points to child ifds, child ifd field definition array */ -}; + struct _TIFFField + { + uint32_t field_tag; /* field's tag */ + short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ + short field_writecount; /* write count/TIFF_VARIABLE */ + TIFFDataType field_type; /* type of associated data */ + uint32_t + field_anonymous; /* if true, this is a unknown / anonymous tag */ + TIFFSetGetFieldType + set_field_type; /* type to be passed to TIFFSetField */ + TIFFSetGetFieldType + get_field_type; /* type to be passed to TIFFGetField */ + unsigned short field_bit; /* bit in fieldsset bit vector */ + unsigned char field_oktochange; /* if true, can change while writing */ + unsigned char field_passcount; /* if true, pass dir count on set */ + char *field_name; /* ASCII name */ + TIFFFieldArray *field_subfields; /* if field points to child ifds, child + ifd field definition array */ + }; -extern int _TIFFMergeFields(TIFF*, const TIFFField[], uint32_t); -extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32_t, TIFFDataType); -extern TIFFField* _TIFFCreateAnonField(TIFF *, uint32_t, TIFFDataType); -extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag); -extern int _TIFFCheckDirNumberAndOffset(TIFF *tif, uint16_t dirn, uint64_t diroff); -extern int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, uint16_t *dirn); + extern int _TIFFMergeFields(TIFF *, const TIFFField[], uint32_t); + extern const TIFFField *_TIFFFindOrRegisterField(TIFF *, uint32_t, + TIFFDataType); + extern TIFFField *_TIFFCreateAnonField(TIFF *, uint32_t, TIFFDataType); + extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag); + extern int _TIFFCheckDirNumberAndOffset(TIFF *tif, uint16_t dirn, + uint64_t diroff); + extern int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, + uint16_t *dirn); #if defined(__cplusplus) } diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c index 2fc40c9f..6a15c766 100644 --- a/libtiff/tif_dirinfo.c +++ b/libtiff/tif_dirinfo.c @@ -42,888 +42,1147 @@ /* const object should be initialized */ #ifdef _MSC_VER -#pragma warning( push ) -#pragma warning( disable : 4132 ) +#pragma warning(push) +#pragma warning(disable : 4132) #endif static const TIFFFieldArray tiffFieldArray; static const TIFFFieldArray exifFieldArray; static const TIFFFieldArray gpsFieldArray; #ifdef _MSC_VER -#pragma warning( pop ) +#pragma warning(pop) #endif /*--: Rational2Double: -- - * The Rational2Double upgraded libtiff functionality allows the definition and achievement of true double-precision accuracy - * for TIFF tags of RATIONAL type and field_bit=FIELD_CUSTOM using the set_field_type = TIFF_SETGET_DOUBLE. + * The Rational2Double upgraded libtiff functionality allows the definition and + * achievement of true double-precision accuracy for TIFF tags of RATIONAL type + * and field_bit=FIELD_CUSTOM using the set_field_type = TIFF_SETGET_DOUBLE. * Unfortunately, that changes the old implemented interface for TIFFGetField(). - * In order to keep the old TIFFGetField() interface behavior those tags have to be redefined with set_field_type = TIFF_SETGET_FLOAT! + * In order to keep the old TIFFGetField() interface behavior those tags have to + * be redefined with set_field_type = TIFF_SETGET_FLOAT! * * Rational custom arrays are already defined as _Cxx_FLOAT, thus can stay. * */ -static const TIFFField -tiffFields[] = { - { TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL }, - { TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "OldSubfileType", NULL }, - { TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL }, - { TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL }, - { TIFFTAG_BITSPERSAMPLE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL }, - { TIFFTAG_COMPRESSION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL }, - { TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL }, - { TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL }, - { TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellWidth", NULL }, - { TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellLength", NULL }, - { TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL }, - { TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL }, - { TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL }, - { TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL }, - { TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL }, - { TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL }, - { TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL }, - { TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL }, - { TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL }, - { TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL }, - { TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL }, - { TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL }, - { TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL }, - { TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL }, - { TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL }, - { TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL }, - { TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL }, - { TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL }, - { TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL }, - { TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL }, - { TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL }, - { TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL }, - { TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL }, - { TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL }, - { TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL }, - { TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL }, - { TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL }, - { TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL }, - { TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL }, - { TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL }, - { TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL }, - { TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL }, - { TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL }, - { TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL }, - { TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL }, - { TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL }, - { TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL }, - { TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL }, - { TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", (TIFFFieldArray*) &tiffFieldArray }, - { TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL }, - { TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL }, - { TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_NUMBEROFINKS, 1, 0, "NumberOfInks", NULL }, - { TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL }, - { TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL }, - { TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL }, - { TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL }, - { TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL }, - { TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL }, - { TIFFTAG_CLIPPATH, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL }, - { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL }, - { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL }, - { TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL }, - { TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL }, - { TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL }, - { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL }, - { TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "XMLPacket", NULL }, - /* begin SGI tags */ - { TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL }, - { TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL }, - { TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL }, - { TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL }, - /* end SGI tags */ - /* begin Pixar tags */ - { TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL }, - { TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL }, - { TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL }, - { TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL }, - { TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL }, - { TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL }, - { TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL }, - { TIFFTAG_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFARepeatPatternDim", NULL }, - { TIFFTAG_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPattern" , NULL}, - { TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL }, - /* end Pixar tags */ - { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL }, - { TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Photoshop", NULL }, - /*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not TIFF_IFD8 as in original LibTiff. - * However, for IFD-like tags, libtiff uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with - * a special handling procedure in order to write either a 32-bit value and the TIFF_IFD type-id into ClassicTIFF files - * or a 64-bit value and the TIFF_IFD8 type-id into BigTIFF files. */ - { TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", (TIFFFieldArray*) &exifFieldArray }, - { TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL }, - { TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", (TIFFFieldArray*) &gpsFieldArray }, - { TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL }, - { TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL }, - { TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL }, - { TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL }, - { TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL }, - { TIFFTAG_IMAGESOURCEDATA, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Adobe Photoshop Document Data Block", NULL }, - { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL }, - /* begin DNG tags */ - { TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL }, - { TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGBackwardVersion", NULL }, - { TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL }, - { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL }, - { TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPlaneColor", NULL }, - { TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFALayout", NULL }, - { TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "LinearizationTable", NULL }, - { TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BlackLevelRepeatDim", NULL }, - { TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevel", NULL }, - { TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaH", NULL }, - { TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaV", NULL }, - { TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "WhiteLevel", NULL }, - { TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultScale", NULL }, - { TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL }, - { TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropOrigin", NULL }, - { TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropSize", NULL }, - { TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix1", NULL }, - { TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix2", NULL }, - { TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration1", NULL }, - { TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration2", NULL }, - { TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix1", NULL }, - { TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix2", NULL }, - { TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AnalogBalance", NULL }, - { TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotNeutral", NULL }, - { TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AsShotWhiteXY", NULL }, - { TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL }, - { TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL }, - { TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL }, - { TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BayerGreenSplit", NULL }, - { TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL }, - { TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL }, - { TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LensInfo", NULL }, - { TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL }, - { TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL }, - { TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL }, - { TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "DNGPrivateData", NULL }, - { TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "MakerNoteSafety", NULL }, - { TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant1", NULL }, - { TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant2", NULL }, - { TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "RawDataUniqueID", NULL }, - { TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL }, - { TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "OriginalRawFileData", NULL }, - { TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ActiveArea", NULL }, - { TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "MaskedAreas", NULL }, - { TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotICCProfile", NULL }, - { TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotPreProfileMatrix", NULL }, - { TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentICCProfile", NULL }, - { TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentPreProfileMatrix", NULL }, - { TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL}, - /* end DNG tags */ - /* begin TIFF/FX tags */ - { TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "Indexed", NULL }, - { TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GlobalParametersIFD", NULL }, - { TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ProfileType", NULL }, - { TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "FaxProfile", NULL }, - { TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CodingMethods", NULL }, - { TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "VersionYear", NULL }, - { TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ModeNumber", NULL }, - { TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Decode", NULL }, - { TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ImageBaseColor", NULL }, - { TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "T82Options", NULL }, - { TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "StripRowCounts", NULL }, - { TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ImageLayer", NULL }, - /* end TIFF/FX tags */ - /* begin pseudo tags */ +static const TIFFField tiffFields[] = { + {TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL}, + {TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "OldSubfileType", NULL}, + {TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL}, + {TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL}, + {TIFFTAG_BITSPERSAMPLE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL}, + {TIFFTAG_COMPRESSION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL}, + {TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, + "PhotometricInterpretation", NULL}, + {TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL}, + {TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellWidth", NULL}, + {TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CellLength", NULL}, + {TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL}, + {TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL}, + {TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL}, + {TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL}, + {TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL}, + {TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL}, + {TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL}, + {TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", + NULL}, + {TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL}, + {TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", + NULL}, + {TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL}, + {TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL}, + {TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL}, + {TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL}, + {TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", + NULL}, + {TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL}, + {TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL}, + {TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL}, + {TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL}, + {TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL}, + {TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL}, + {TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL}, + {TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL}, + {TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, + TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL}, + {TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL}, + {TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, + TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", + NULL}, + {TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL}, + {TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL}, + {TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL}, + {TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL}, + {TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL}, + {TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, + TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, + "PrimaryChromaticities", NULL}, + {TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, + TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL}, + {TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, + TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL}, + {TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL}, + {TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL}, + {TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL}, + {TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", + NULL}, + {TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, + TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", + (TIFFFieldArray *)&tiffFieldArray}, + {TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL}, + {TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL}, + {TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_NUMBEROFINKS, 1, 0, "NumberOfInks", NULL}, + {TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL}, + {TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL}, + {TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL}, + {TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL}, + {TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", + NULL}, + {TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", + NULL}, + {TIFFTAG_CLIPPATH, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL}, + {TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL}, + {TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL}, + {TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL}, + {TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, + TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", + NULL}, + {TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", + NULL}, + {TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", + NULL}, + {TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "XMLPacket", NULL}, + /* begin SGI tags */ + {TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL}, + {TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL}, + {TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL}, + {TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL}, + /* end SGI tags */ + /* begin Pixar tags */ + {TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL}, + {TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL}, + {TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL}, + {TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL}, + {TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL}, + {TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, + TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, + "MatrixWorldToScreen", NULL}, + {TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, + TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, + "MatrixWorldToCamera", NULL}, + {TIFFTAG_CFAREPEATPATTERNDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFARepeatPatternDim", NULL}, + {TIFFTAG_CFAPATTERN, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPattern", NULL}, + {TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL}, + /* end Pixar tags */ + {TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL}, + {TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "Photoshop", NULL}, + /*--: EXIFIFD and GPSIFD specified as TIFF_LONG by Aware-Systems and not + * TIFF_IFD8 as in original LibTiff. However, for IFD-like tags, libtiff + * uses the data type TIFF_IFD8 in tiffFields[]-tag definition combined with + * a special handling procedure in order to write either a 32-bit value + * and the TIFF_IFD type-id into ClassicTIFF files or a 64-bit value and the + * TIFF_IFD8 type-id into BigTIFF files. */ + {TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "EXIFIFDOffset", + (TIFFFieldArray *)&exifFieldArray}, + {TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL}, + {TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GPSIFDOffset", + (TIFFFieldArray *)&gpsFieldArray}, + {TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL}, + {TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL}, + {TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL}, + {TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL}, + {TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL}, + {TIFFTAG_IMAGESOURCEDATA, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, + "Adobe Photoshop Document Data Block", NULL}, + {TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", + NULL}, + /* begin DNG tags */ + {TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL}, + {TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGBackwardVersion", NULL}, + {TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL}, + {TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL}, + {TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPlaneColor", NULL}, + {TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFALayout", NULL}, + {TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "LinearizationTable", NULL}, + {TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BlackLevelRepeatDim", NULL}, + {TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevel", NULL}, + {TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaH", NULL}, + {TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaV", NULL}, + {TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "WhiteLevel", NULL}, + {TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultScale", NULL}, + {TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL}, + {TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropOrigin", NULL}, + {TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropSize", NULL}, + {TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix1", NULL}, + {TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix2", NULL}, + {TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, + TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, + "CameraCalibration1", NULL}, + {TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, + TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, + "CameraCalibration2", NULL}, + {TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix1", NULL}, + {TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix2", NULL}, + {TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AnalogBalance", NULL}, + {TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotNeutral", NULL}, + {TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AsShotWhiteXY", NULL}, + {TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL}, + {TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL}, + {TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL}, + {TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BayerGreenSplit", NULL}, + {TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL}, + {TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL}, + {TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LensInfo", NULL}, + {TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL}, + {TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL}, + {TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL}, + {TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "DNGPrivateData", NULL}, + {TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "MakerNoteSafety", NULL}, + {TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant1", NULL}, + {TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant2", NULL}, + {TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "RawDataUniqueID", NULL}, + {TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL}, + {TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, + TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, + "OriginalRawFileData", NULL}, + {TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ActiveArea", NULL}, + {TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "MaskedAreas", NULL}, + {TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotICCProfile", NULL}, + {TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, + TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, + "AsShotPreProfileMatrix", NULL}, + {TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, + TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, + "CurrentICCProfile", NULL}, + {TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, + TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, + "CurrentPreProfileMatrix", NULL}, + {TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL}, + /* end DNG tags */ + /* begin TIFF/FX tags */ + {TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "Indexed", NULL}, + {TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GlobalParametersIFD", NULL}, + {TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ProfileType", NULL}, + {TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "FaxProfile", NULL}, + {TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CodingMethods", NULL}, + {TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "VersionYear", NULL}, + {TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ModeNumber", NULL}, + {TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Decode", NULL}, + {TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ImageBaseColor", NULL}, + {TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "T82Options", NULL}, + {TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "StripRowCounts", NULL}, + {TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ImageLayer", NULL}, + /* end TIFF/FX tags */ + /* begin pseudo tags */ }; /* * EXIF tags (Version 2.31, July 2016 plus version 2.32 May 2019) */ -static const TIFFField -exifFields[] = { - { EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL }, - { EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL }, - { EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL }, - { EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL }, - { EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL }, - { EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL }, - { EXIFTAG_SENSITIVITYTYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensitivityType", NULL }, - { EXIFTAG_STANDARDOUTPUTSENSITIVITY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "StandardOutputSensitivity", NULL }, - { EXIFTAG_RECOMMENDEDEXPOSUREINDEX, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RecommendedExposureIndex", NULL }, - { EXIFTAG_ISOSPEED, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeed", NULL }, - { EXIFTAG_ISOSPEEDLATITUDEYYY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudeyyy", NULL }, - { EXIFTAG_ISOSPEEDLATITUDEZZZ, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudezzz", NULL }, - { EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL }, - { EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL }, - { EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL }, - { EXIFTAG_OFFSETTIME, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTime", NULL }, - { EXIFTAG_OFFSETTIMEORIGINAL, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeOriginal", NULL }, - { EXIFTAG_OFFSETTIMEDIGITIZED, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeDigitized", NULL }, - { EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL }, - { EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL }, - { EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL }, - { EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL }, - { EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL }, - { EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL }, - { EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL }, - /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator equals 4294967295 (0xFFFFFFFF) to indicate infinite distance! - * However, there are two other EXIF tags where numerator indicates a special value and six other cases where the denominator indicates special values, - * which are not treated within LibTiff!! */ - { EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL }, - { EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL }, - { EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL }, - { EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL }, - { EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL }, - { EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL }, - { EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL }, - { EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL }, - { EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL }, - { EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL }, - { EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL }, - { EXIFTAG_TEMPERATURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Temperature", NULL }, - { EXIFTAG_HUMIDITY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Humidity", NULL }, - { EXIFTAG_PRESSURE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Pressure", NULL }, - { EXIFTAG_WATERDEPTH, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WaterDepth", NULL }, - { EXIFTAG_ACCELERATION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Acceleration", NULL }, - { EXIFTAG_CAMERAELEVATIONANGLE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraElevationAngle", NULL }, - { EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL }, - { EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL }, - { EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL }, - { EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL }, - { EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL }, - { EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL }, - { EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL }, - { EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL }, - { EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL }, - { EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL }, - { EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL }, - { EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL }, - { EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL }, - { EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL }, - { EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL }, - { EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL }, - { EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL }, - { EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL }, - { EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL }, - { EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL }, - { EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL }, - { EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL }, - { EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL }, - { EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL }, - { EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL }, - { EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL }, - { EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL }, - { EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL }, - { EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL }, - { EXIFTAG_CAMERAOWNERNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraOwnerName", NULL }, - { EXIFTAG_BODYSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BodySerialNumber", NULL }, - { EXIFTAG_LENSSPECIFICATION, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSpecification", NULL }, - { EXIFTAG_LENSMAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensMake", NULL }, - { EXIFTAG_LENSMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensModel", NULL }, - { EXIFTAG_LENSSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSerialNumber", NULL }, - { EXIFTAG_GAMMA, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Gamma", NULL }, - { EXIFTAG_COMPOSITEIMAGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompositeImage", NULL }, - { EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SourceImageNumberOfCompositeImage", NULL }, - { EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SourceExposureTimesOfCompositeImage", NULL } -}; +static const TIFFField exifFields[] = { + {EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL}, + {EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL}, + {EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL}, + {EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL}, + {EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL}, + {EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", + NULL}, + {EXIFTAG_SENSITIVITYTYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensitivityType", NULL}, + {EXIFTAG_STANDARDOUTPUTSENSITIVITY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "StandardOutputSensitivity", + NULL}, + {EXIFTAG_RECOMMENDEDEXPOSUREINDEX, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RecommendedExposureIndex", + NULL}, + {EXIFTAG_ISOSPEED, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeed", NULL}, + {EXIFTAG_ISOSPEEDLATITUDEYYY, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudeyyy", NULL}, + {EXIFTAG_ISOSPEEDLATITUDEZZZ, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ISOSpeedLatitudezzz", NULL}, + {EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL}, + {EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL}, + {EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL}, + {EXIFTAG_OFFSETTIME, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTime", NULL}, + {EXIFTAG_OFFSETTIMEORIGINAL, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeOriginal", NULL}, + {EXIFTAG_OFFSETTIMEDIGITIZED, 7, 7, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "OffsetTimeDigitized", NULL}, + {EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, + TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, + "ComponentsConfiguration", NULL}, + {EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL}, + {EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL}, + {EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL}, + {EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL}, + {EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL}, + {EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL}, + /*--: EXIFTAG_SUBJECTDISTANCE: LibTiff returns value of "-1" if numerator + * equals 4294967295 (0xFFFFFFFF) to indicate infinite distance! However, + * there are two other EXIF tags where numerator indicates a special value + * and six other cases where the denominator indicates special values, which + * are not treated within LibTiff!! */ + {EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL}, + {EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL}, + {EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL}, + {EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL}, + {EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL}, + {EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL}, + {EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL}, + {EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL}, + {EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL}, + {EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL}, + {EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL}, + {EXIFTAG_TEMPERATURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Temperature", NULL}, + {EXIFTAG_HUMIDITY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Humidity", NULL}, + {EXIFTAG_PRESSURE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Pressure", NULL}, + {EXIFTAG_WATERDEPTH, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WaterDepth", NULL}, + {EXIFTAG_ACCELERATION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Acceleration", NULL}, + {EXIFTAG_CAMERAELEVATIONANGLE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraElevationAngle", NULL}, + {EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL}, + {EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL}, + {EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL}, + {EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL}, + {EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL}, + {EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL}, + {EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, + TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, + "SpatialFrequencyResponse", NULL}, + {EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL}, + {EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL}, + {EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", + NULL}, + {EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL}, + {EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL}, + {EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL}, + {EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL}, + {EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL}, + {EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL}, + {EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL}, + {EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL}, + {EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL}, + {EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL}, + {EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL}, + {EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL}, + {EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL}, + {EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL}, + {EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL}, + {EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL}, + {EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, + TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, + "DeviceSettingDescription", NULL}, + {EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL}, + {EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL}, + {EXIFTAG_CAMERAOWNERNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraOwnerName", NULL}, + {EXIFTAG_BODYSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BodySerialNumber", NULL}, + {EXIFTAG_LENSSPECIFICATION, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSpecification", NULL}, + {EXIFTAG_LENSMAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensMake", NULL}, + {EXIFTAG_LENSMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensModel", NULL}, + {EXIFTAG_LENSSERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LensSerialNumber", NULL}, + {EXIFTAG_GAMMA, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_FLOAT, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Gamma", NULL}, + {EXIFTAG_COMPOSITEIMAGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompositeImage", NULL}, + {EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE, 2, 2, TIFF_SHORT, 0, + TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, + "SourceImageNumberOfCompositeImage", NULL}, + {EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE, -1, -1, TIFF_UNDEFINED, 0, + TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, + "SourceExposureTimesOfCompositeImage", NULL}}; /* - * EXIF-GPS tags (Version 2.31, July 2016; nothing changed for version 2.32 May 2019) + * EXIF-GPS tags (Version 2.31, July 2016; nothing changed for version 2.32 May + * 2019) */ -static const TIFFField -gpsFields[] = { - /* For the GPS tag definitions in gpsFields[] the standard definition for Rationals is TIFF_SETGET_DOUBLE and TIFF_SETGET_C0_FLOAT. - *-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values can now be written and also read in double precision! - * In order to achieve double precision for GPS tags: - * Standard definitions for GPSTAG is kept to TIFF_SETGET_DOUBLE - * and TIFF_SETGET_C0_FLOAT is changed to TIFF_SETGET_C0_DOUBLE. - */ - { GPSTAG_VERSIONID , 4, 4, TIFF_BYTE , 0, TIFF_SETGET_C0_UINT8 , TIFF_SETGET_UINT8 , FIELD_CUSTOM , 1, 0, "VersionID", NULL }, - { GPSTAG_LATITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "LatitudeRef", NULL }, - { GPSTAG_LATITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Latitude", NULL }, - { GPSTAG_LONGITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "LongitudeRef", NULL }, - { GPSTAG_LONGITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Longitude", NULL }, - { GPSTAG_ALTITUDEREF , 1, 1, TIFF_BYTE , 0, TIFF_SETGET_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "AltitudeRef", NULL }, - { GPSTAG_ALTITUDE , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Altitude", NULL }, - { GPSTAG_TIMESTAMP , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "TimeStamp", NULL }, - { GPSTAG_SATELLITES , -1, -1, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Satellites", NULL }, - { GPSTAG_STATUS , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Status", NULL }, - { GPSTAG_MEASUREMODE , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "MeasureMode", NULL }, - { GPSTAG_DOP , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DOP", NULL }, - { GPSTAG_SPEEDREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "SpeedRef", NULL }, - { GPSTAG_SPEED , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Speed", NULL }, - { GPSTAG_TRACKREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "TrackRef", NULL }, - { GPSTAG_TRACK , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Track", NULL }, - { GPSTAG_IMGDIRECTIONREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "ImgDirectionRef", NULL }, - { GPSTAG_IMGDIRECTION , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "ImgDirection", NULL }, - { GPSTAG_MAPDATUM , -1, -1, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "MapDatum", NULL }, - { GPSTAG_DESTLATITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLatitudeRef", NULL }, - { GPSTAG_DESTLATITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLatitude", NULL }, - { GPSTAG_DESTLONGITUDEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLongitudeRef", NULL }, - { GPSTAG_DESTLONGITUDE , 3, 3, TIFF_RATIONAL , 0, TIFF_SETGET_C0_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestLongitude", NULL }, - { GPSTAG_DESTBEARINGREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestBearingRef", NULL }, - { GPSTAG_DESTBEARING , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestBearing", NULL }, - { GPSTAG_DESTDISTANCEREF , 2, 2, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestDistanceRef", NULL }, - { GPSTAG_DESTDISTANCE , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DestDistance", NULL }, - { GPSTAG_PROCESSINGMETHOD , -1, -1, TIFF_UNDEFINED , 0, TIFF_SETGET_C16_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 1, "ProcessingMethod", NULL }, - { GPSTAG_AREAINFORMATION , -1, -1, TIFF_UNDEFINED , 0, TIFF_SETGET_C16_UINT8 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 1, "AreaInformation", NULL }, - { GPSTAG_DATESTAMP , 11, 11, TIFF_ASCII , 0, TIFF_SETGET_ASCII , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "DateStamp", NULL }, - { GPSTAG_DIFFERENTIAL , 1, 1, TIFF_SHORT , 0, TIFF_SETGET_UINT16 , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "Differential", NULL }, - { GPSTAG_GPSHPOSITIONINGERROR , 1, 1, TIFF_RATIONAL , 0, TIFF_SETGET_DOUBLE , TIFF_SETGET_UNDEFINED , FIELD_CUSTOM , 1, 0, "HorizontalPositioningError", NULL } -}; - -static const TIFFFieldArray -tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField*) tiffFields }; -static const TIFFFieldArray -exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), (TIFFField*) exifFields }; -static const TIFFFieldArray -gpsFieldArray = { tfiatGps, 0, TIFFArrayCount(gpsFields), (TIFFField*) gpsFields }; +static const TIFFField gpsFields[] = { + /* For the GPS tag definitions in gpsFields[] the standard definition for + *Rationals is TIFF_SETGET_DOUBLE and TIFF_SETGET_C0_FLOAT. + *-- ATTENTION: After the upgrade with Rational2Double, the GPSTAG values + *can now be written and also read in double precision! In order to achieve + *double precision for GPS tags: Standard definitions for GPSTAG is kept to + *TIFF_SETGET_DOUBLE and TIFF_SETGET_C0_FLOAT is changed to + *TIFF_SETGET_C0_DOUBLE. + */ + {GPSTAG_VERSIONID, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, + TIFF_SETGET_UINT8, FIELD_CUSTOM, 1, 0, "VersionID", NULL}, + {GPSTAG_LATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LatitudeRef", NULL}, + {GPSTAG_LATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Latitude", NULL}, + {GPSTAG_LONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LongitudeRef", NULL}, + {GPSTAG_LONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Longitude", NULL}, + {GPSTAG_ALTITUDEREF, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "AltitudeRef", NULL}, + {GPSTAG_ALTITUDE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Altitude", NULL}, + {GPSTAG_TIMESTAMP, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TimeStamp", NULL}, + {GPSTAG_SATELLITES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Satellites", NULL}, + {GPSTAG_STATUS, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Status", NULL}, + {GPSTAG_MEASUREMODE, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeasureMode", NULL}, + {GPSTAG_DOP, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DOP", NULL}, + {GPSTAG_SPEEDREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpeedRef", NULL}, + {GPSTAG_SPEED, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Speed", NULL}, + {GPSTAG_TRACKREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TrackRef", NULL}, + {GPSTAG_TRACK, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Track", NULL}, + {GPSTAG_IMGDIRECTIONREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImgDirectionRef", NULL}, + {GPSTAG_IMGDIRECTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImgDirection", NULL}, + {GPSTAG_MAPDATUM, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MapDatum", NULL}, + {GPSTAG_DESTLATITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLatitudeRef", NULL}, + {GPSTAG_DESTLATITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLatitude", NULL}, + {GPSTAG_DESTLONGITUDEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLongitudeRef", NULL}, + {GPSTAG_DESTLONGITUDE, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestLongitude", NULL}, + {GPSTAG_DESTBEARINGREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestBearingRef", NULL}, + {GPSTAG_DESTBEARING, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestBearing", NULL}, + {GPSTAG_DESTDISTANCEREF, 2, 2, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestDistanceRef", NULL}, + {GPSTAG_DESTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DestDistance", NULL}, + {GPSTAG_PROCESSINGMETHOD, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ProcessingMethod", NULL}, + {GPSTAG_AREAINFORMATION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "AreaInformation", NULL}, + {GPSTAG_DATESTAMP, 11, 11, TIFF_ASCII, 0, TIFF_SETGET_ASCII, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateStamp", NULL}, + {GPSTAG_DIFFERENTIAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Differential", NULL}, + {GPSTAG_GPSHPOSITIONINGERROR, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HorizontalPositioningError", + NULL}}; + +static const TIFFFieldArray tiffFieldArray = { + tfiatImage, 0, TIFFArrayCount(tiffFields), (TIFFField *)tiffFields}; +static const TIFFFieldArray exifFieldArray = { + tfiatExif, 0, TIFFArrayCount(exifFields), (TIFFField *)exifFields}; +static const TIFFFieldArray gpsFieldArray = { + tfiatGps, 0, TIFFArrayCount(gpsFields), (TIFFField *)gpsFields}; /* * We have our own local lfind() equivalent to avoid subtle differences - * in types passed to lfind() on different systems. + * in types passed to lfind() on different systems. */ -static void * -td_lfind(const void *key, const void *base, size_t *nmemb, size_t size, - int(*compar)(const void *, const void *)) +static void *td_lfind(const void *key, const void *base, size_t *nmemb, + size_t size, int (*compar)(const void *, const void *)) { char *element, *end; end = (char *)base + *nmemb * size; for (element = (char *)base; element < end; element += size) - if (!compar(key, element)) /* key found */ + if (!compar(key, element)) /* key found */ return element; return NULL; } -const TIFFFieldArray* -_TIFFGetFields(void) -{ - return(&tiffFieldArray); -} +const TIFFFieldArray *_TIFFGetFields(void) { return (&tiffFieldArray); } -const TIFFFieldArray* -_TIFFGetExifFields(void) -{ - return(&exifFieldArray); -} +const TIFFFieldArray *_TIFFGetExifFields(void) { return (&exifFieldArray); } -const TIFFFieldArray* -_TIFFGetGpsFields(void) -{ - return(&gpsFieldArray); -} +const TIFFFieldArray *_TIFFGetGpsFields(void) { return (&gpsFieldArray); } -void -_TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray) +void _TIFFSetupFields(TIFF *tif, const TIFFFieldArray *fieldarray) { - if (tif->tif_fields && tif->tif_nfields > 0) { - uint32_t i; - - for (i = 0; i < tif->tif_nfields; i++) { - TIFFField *fld = tif->tif_fields[i]; - if (fld->field_name != NULL) { - if (fld->field_bit == FIELD_CUSTOM && - TIFFFieldIsAnonymous(fld)) { - _TIFFfreeExt(tif, fld->field_name); - /* caution: tif_fields[i] must not be the beginning of a fields-array. - * Otherwise the following tags are also freed with the first free(). - */ - _TIFFfreeExt(tif, fld); - } - } - } - - _TIFFfreeExt(tif, tif->tif_fields); - tif->tif_fields = NULL; - tif->tif_nfields = 0; - } - if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) { - TIFFErrorExtR(tif, "_TIFFSetupFields", - "Setting up field info failed"); - } + if (tif->tif_fields && tif->tif_nfields > 0) + { + uint32_t i; + + for (i = 0; i < tif->tif_nfields; i++) + { + TIFFField *fld = tif->tif_fields[i]; + if (fld->field_name != NULL) + { + if (fld->field_bit == FIELD_CUSTOM && TIFFFieldIsAnonymous(fld)) + { + _TIFFfreeExt(tif, fld->field_name); + /* caution: tif_fields[i] must not be the beginning of a + * fields-array. Otherwise the following tags are also freed + * with the first free(). + */ + _TIFFfreeExt(tif, fld); + } + } + } + + _TIFFfreeExt(tif, tif->tif_fields); + tif->tif_fields = NULL; + tif->tif_nfields = 0; + } + if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) + { + TIFFErrorExtR(tif, "_TIFFSetupFields", "Setting up field info failed"); + } } -static int -tagCompare(const void* a, const void* b) +static int tagCompare(const void *a, const void *b) { - const TIFFField* ta = *(const TIFFField**) a; - const TIFFField* tb = *(const TIFFField**) b; - /* NB: be careful of return values for 16-bit platforms */ - if (ta->field_tag != tb->field_tag) - return (int)ta->field_tag - (int)tb->field_tag; - else - return (ta->field_type == TIFF_ANY) ? - 0 : ((int)tb->field_type - (int)ta->field_type); + const TIFFField *ta = *(const TIFFField **)a; + const TIFFField *tb = *(const TIFFField **)b; + /* NB: be careful of return values for 16-bit platforms */ + if (ta->field_tag != tb->field_tag) + return (int)ta->field_tag - (int)tb->field_tag; + else + return (ta->field_type == TIFF_ANY) + ? 0 + : ((int)tb->field_type - (int)ta->field_type); } -static int -tagNameCompare(const void* a, const void* b) +static int tagNameCompare(const void *a, const void *b) { - const TIFFField* ta = *(const TIFFField**) a; - const TIFFField* tb = *(const TIFFField**) b; - int ret = strcmp(ta->field_name, tb->field_name); - - if (ret) - return ret; - else - return (ta->field_type == TIFF_ANY) ? - 0 : ((int)tb->field_type - (int)ta->field_type); + const TIFFField *ta = *(const TIFFField **)a; + const TIFFField *tb = *(const TIFFField **)b; + int ret = strcmp(ta->field_name, tb->field_name); + + if (ret) + return ret; + else + return (ta->field_type == TIFF_ANY) + ? 0 + : ((int)tb->field_type - (int)ta->field_type); } -int -_TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32_t n) +int _TIFFMergeFields(TIFF *tif, const TIFFField info[], uint32_t n) { - static const char module[] = "_TIFFMergeFields"; - static const char reason[] = "for fields array"; - /* TIFFField** tp; */ - uint32_t i; - - tif->tif_foundfield = NULL; - - if (tif->tif_fields && tif->tif_nfields > 0) { - tif->tif_fields = (TIFFField**) - _TIFFCheckRealloc(tif, tif->tif_fields, - (tif->tif_nfields + n), - sizeof(TIFFField *), reason); - } else { - tif->tif_fields = (TIFFField **) - _TIFFCheckMalloc(tif, n, sizeof(TIFFField *), - reason); - } - if (!tif->tif_fields) { - TIFFErrorExtR(tif, module, - "Failed to allocate fields array"); - return 0; - } - - /* tp = tif->tif_fields + tif->tif_nfields; */ - for (i = 0; i < n; i++) { - const TIFFField *fip = - TIFFFindField(tif, info[i].field_tag, TIFF_ANY); - - /* only add definitions that aren't already present */ - if (!fip) { - tif->tif_fields[tif->tif_nfields] = (TIFFField *) (info+i); - tif->tif_nfields++; - } - } - - /* Sort the field info by tag number */ - qsort(tif->tif_fields, tif->tif_nfields, - sizeof(TIFFField *), tagCompare); - - return n; + static const char module[] = "_TIFFMergeFields"; + static const char reason[] = "for fields array"; + /* TIFFField** tp; */ + uint32_t i; + + tif->tif_foundfield = NULL; + + if (tif->tif_fields && tif->tif_nfields > 0) + { + tif->tif_fields = (TIFFField **)_TIFFCheckRealloc( + tif, tif->tif_fields, (tif->tif_nfields + n), sizeof(TIFFField *), + reason); + } + else + { + tif->tif_fields = + (TIFFField **)_TIFFCheckMalloc(tif, n, sizeof(TIFFField *), reason); + } + if (!tif->tif_fields) + { + TIFFErrorExtR(tif, module, "Failed to allocate fields array"); + return 0; + } + + /* tp = tif->tif_fields + tif->tif_nfields; */ + for (i = 0; i < n; i++) + { + const TIFFField *fip = TIFFFindField(tif, info[i].field_tag, TIFF_ANY); + + /* only add definitions that aren't already present */ + if (!fip) + { + tif->tif_fields[tif->tif_nfields] = (TIFFField *)(info + i); + tif->tif_nfields++; + } + } + + /* Sort the field info by tag number */ + qsort(tif->tif_fields, tif->tif_nfields, sizeof(TIFFField *), tagCompare); + + return n; } -void -_TIFFPrintFieldInfo(TIFF* tif, FILE* fd) +void _TIFFPrintFieldInfo(TIFF *tif, FILE *fd) { - uint32_t i; - - fprintf(fd, "%s: \n", tif->tif_name); - for (i = 0; i < tif->tif_nfields; i++) { - const TIFFField* fip = tif->tif_fields[i]; - fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n" - , (int)i - , (unsigned long) fip->field_tag - , fip->field_readcount, fip->field_writecount - , fip->field_type - , fip->field_bit - , fip->field_oktochange ? "TRUE" : "FALSE" - , fip->field_passcount ? "TRUE" : "FALSE" - , fip->field_name - ); - } + uint32_t i; + + fprintf(fd, "%s: \n", tif->tif_name); + for (i = 0; i < tif->tif_nfields; i++) + { + const TIFFField *fip = tif->tif_fields[i]; + fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n", + (int)i, (unsigned long)fip->field_tag, fip->field_readcount, + fip->field_writecount, fip->field_type, fip->field_bit, + fip->field_oktochange ? "TRUE" : "FALSE", + fip->field_passcount ? "TRUE" : "FALSE", fip->field_name); + } } /* * Return size of TIFFDataType within TIFF-file in bytes */ -int -TIFFDataWidth(TIFFDataType type) +int TIFFDataWidth(TIFFDataType type) { - switch(type) - { - case 0: /* nothing */ - case TIFF_BYTE: - case TIFF_ASCII: - case TIFF_SBYTE: - case TIFF_UNDEFINED: - return 1; - case TIFF_SHORT: - case TIFF_SSHORT: - return 2; - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_FLOAT: - case TIFF_IFD: - return 4; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_DOUBLE: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_IFD8: - return 8; - default: - return 0; /* will return 0 for unknown types */ - } + switch (type) + { + case 0: /* nothing */ + case TIFF_BYTE: + case TIFF_ASCII: + case TIFF_SBYTE: + case TIFF_UNDEFINED: + return 1; + case TIFF_SHORT: + case TIFF_SSHORT: + return 2; + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_FLOAT: + case TIFF_IFD: + return 4; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_DOUBLE: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_IFD8: + return 8; + default: + return 0; /* will return 0 for unknown types */ + } } - -/* +/* * Return internal storage size of TIFFSetGetFieldType in bytes. * TIFFSetField() and TIFFGetField() have to provide the parameter accordingly. - * Replaces internal functions _TIFFDataSize() and _TIFFSetGetFieldSize() + * Replaces internal functions _TIFFDataSize() and _TIFFSetGetFieldSize() * with now extern available function TIFFFieldSetGetSize(). */ -int -TIFFFieldSetGetSize(const TIFFField* fip) +int TIFFFieldSetGetSize(const TIFFField *fip) { -/* - * TIFFSetField() and TIFFGetField() must provide the parameter accordingly to - * the definition of "set_field_type" of the tag definition in dir_info.c. - * This function returns the data size for that purpose. - * - * Furthermore, this data size is also used for the internal storage, - * even for TIFF_RATIONAL values for FIELD_CUSTOM, which are stored internally as 4-byte float, - * but some of them should be stored internally as 8-byte double, - * depending on the "set_field_type" _FLOAT_ or _DOUBLE_. -*/ - if (fip == NULL) return 0; - - switch (fip->set_field_type) - { - case TIFF_SETGET_UNDEFINED: - case TIFF_SETGET_ASCII: - case TIFF_SETGET_C0_ASCII: - case TIFF_SETGET_C16_ASCII: - case TIFF_SETGET_C32_ASCII: - case TIFF_SETGET_OTHER: - return 1; - case TIFF_SETGET_UINT8: - case TIFF_SETGET_SINT8: - case TIFF_SETGET_C0_UINT8: - case TIFF_SETGET_C0_SINT8: - case TIFF_SETGET_C16_UINT8: - case TIFF_SETGET_C16_SINT8: - case TIFF_SETGET_C32_UINT8: - case TIFF_SETGET_C32_SINT8: - return 1; - case TIFF_SETGET_UINT16: - case TIFF_SETGET_SINT16: - case TIFF_SETGET_C0_UINT16: - case TIFF_SETGET_C0_SINT16: - case TIFF_SETGET_C16_UINT16: - case TIFF_SETGET_C16_SINT16: - case TIFF_SETGET_C32_UINT16: - case TIFF_SETGET_C32_SINT16: - return 2; - case TIFF_SETGET_INT: - case TIFF_SETGET_UINT32: - case TIFF_SETGET_SINT32: - case TIFF_SETGET_FLOAT: - case TIFF_SETGET_UINT16_PAIR: - case TIFF_SETGET_C0_UINT32: - case TIFF_SETGET_C0_SINT32: - case TIFF_SETGET_C0_FLOAT: - case TIFF_SETGET_C16_UINT32: - case TIFF_SETGET_C16_SINT32: - case TIFF_SETGET_C16_FLOAT: - case TIFF_SETGET_C32_UINT32: - case TIFF_SETGET_C32_SINT32: - case TIFF_SETGET_C32_FLOAT: - return 4; - case TIFF_SETGET_UINT64: - case TIFF_SETGET_SINT64: - case TIFF_SETGET_DOUBLE: - case TIFF_SETGET_IFD8: - case TIFF_SETGET_C0_UINT64: - case TIFF_SETGET_C0_SINT64: - case TIFF_SETGET_C0_DOUBLE: - case TIFF_SETGET_C0_IFD8: - case TIFF_SETGET_C16_UINT64: - case TIFF_SETGET_C16_SINT64: - case TIFF_SETGET_C16_DOUBLE: - case TIFF_SETGET_C16_IFD8: - case TIFF_SETGET_C32_UINT64: - case TIFF_SETGET_C32_SINT64: - case TIFF_SETGET_C32_DOUBLE: - case TIFF_SETGET_C32_IFD8: - return 8; - default: - return 0; - } + /* + * TIFFSetField() and TIFFGetField() must provide the parameter accordingly + * to the definition of "set_field_type" of the tag definition in + * dir_info.c. This function returns the data size for that purpose. + * + * Furthermore, this data size is also used for the internal storage, + * even for TIFF_RATIONAL values for FIELD_CUSTOM, which are stored + * internally as 4-byte float, but some of them should be stored internally + * as 8-byte double, depending on the "set_field_type" _FLOAT_ or _DOUBLE_. + */ + if (fip == NULL) + return 0; + + switch (fip->set_field_type) + { + case TIFF_SETGET_UNDEFINED: + case TIFF_SETGET_ASCII: + case TIFF_SETGET_C0_ASCII: + case TIFF_SETGET_C16_ASCII: + case TIFF_SETGET_C32_ASCII: + case TIFF_SETGET_OTHER: + return 1; + case TIFF_SETGET_UINT8: + case TIFF_SETGET_SINT8: + case TIFF_SETGET_C0_UINT8: + case TIFF_SETGET_C0_SINT8: + case TIFF_SETGET_C16_UINT8: + case TIFF_SETGET_C16_SINT8: + case TIFF_SETGET_C32_UINT8: + case TIFF_SETGET_C32_SINT8: + return 1; + case TIFF_SETGET_UINT16: + case TIFF_SETGET_SINT16: + case TIFF_SETGET_C0_UINT16: + case TIFF_SETGET_C0_SINT16: + case TIFF_SETGET_C16_UINT16: + case TIFF_SETGET_C16_SINT16: + case TIFF_SETGET_C32_UINT16: + case TIFF_SETGET_C32_SINT16: + return 2; + case TIFF_SETGET_INT: + case TIFF_SETGET_UINT32: + case TIFF_SETGET_SINT32: + case TIFF_SETGET_FLOAT: + case TIFF_SETGET_UINT16_PAIR: + case TIFF_SETGET_C0_UINT32: + case TIFF_SETGET_C0_SINT32: + case TIFF_SETGET_C0_FLOAT: + case TIFF_SETGET_C16_UINT32: + case TIFF_SETGET_C16_SINT32: + case TIFF_SETGET_C16_FLOAT: + case TIFF_SETGET_C32_UINT32: + case TIFF_SETGET_C32_SINT32: + case TIFF_SETGET_C32_FLOAT: + return 4; + case TIFF_SETGET_UINT64: + case TIFF_SETGET_SINT64: + case TIFF_SETGET_DOUBLE: + case TIFF_SETGET_IFD8: + case TIFF_SETGET_C0_UINT64: + case TIFF_SETGET_C0_SINT64: + case TIFF_SETGET_C0_DOUBLE: + case TIFF_SETGET_C0_IFD8: + case TIFF_SETGET_C16_UINT64: + case TIFF_SETGET_C16_SINT64: + case TIFF_SETGET_C16_DOUBLE: + case TIFF_SETGET_C16_IFD8: + case TIFF_SETGET_C32_UINT64: + case TIFF_SETGET_C32_SINT64: + case TIFF_SETGET_C32_DOUBLE: + case TIFF_SETGET_C32_IFD8: + return 8; + default: + return 0; + } } /*-- TIFFFieldSetGetSize() --- */ /* * Return size of count parameter of TIFFSetField() and TIFFGetField() - * and also if it is required: 0=none, 2=uint16_t, 4=uint32_t + * and also if it is required: 0=none, 2=uint16_t, 4=uint32_t */ -int -TIFFFieldSetGetCountSize(const TIFFField* fip) +int TIFFFieldSetGetCountSize(const TIFFField *fip) { - if (fip == NULL) return 0; - - switch (fip->set_field_type) { - case TIFF_SETGET_C16_ASCII: - case TIFF_SETGET_C16_UINT8: - case TIFF_SETGET_C16_SINT8: - case TIFF_SETGET_C16_UINT16: - case TIFF_SETGET_C16_SINT16: - case TIFF_SETGET_C16_UINT32: - case TIFF_SETGET_C16_SINT32: - case TIFF_SETGET_C16_FLOAT: - case TIFF_SETGET_C16_UINT64: - case TIFF_SETGET_C16_SINT64: - case TIFF_SETGET_C16_DOUBLE: - case TIFF_SETGET_C16_IFD8: - return 2; - case TIFF_SETGET_C32_ASCII: - case TIFF_SETGET_C32_UINT8: - case TIFF_SETGET_C32_SINT8: - case TIFF_SETGET_C32_UINT16: - case TIFF_SETGET_C32_SINT16: - case TIFF_SETGET_C32_UINT32: - case TIFF_SETGET_C32_SINT32: - case TIFF_SETGET_C32_FLOAT: - case TIFF_SETGET_C32_UINT64: - case TIFF_SETGET_C32_SINT64: - case TIFF_SETGET_C32_DOUBLE: - case TIFF_SETGET_C32_IFD8: - return 4; - default: - return 0; - } + if (fip == NULL) + return 0; + + switch (fip->set_field_type) + { + case TIFF_SETGET_C16_ASCII: + case TIFF_SETGET_C16_UINT8: + case TIFF_SETGET_C16_SINT8: + case TIFF_SETGET_C16_UINT16: + case TIFF_SETGET_C16_SINT16: + case TIFF_SETGET_C16_UINT32: + case TIFF_SETGET_C16_SINT32: + case TIFF_SETGET_C16_FLOAT: + case TIFF_SETGET_C16_UINT64: + case TIFF_SETGET_C16_SINT64: + case TIFF_SETGET_C16_DOUBLE: + case TIFF_SETGET_C16_IFD8: + return 2; + case TIFF_SETGET_C32_ASCII: + case TIFF_SETGET_C32_UINT8: + case TIFF_SETGET_C32_SINT8: + case TIFF_SETGET_C32_UINT16: + case TIFF_SETGET_C32_SINT16: + case TIFF_SETGET_C32_UINT32: + case TIFF_SETGET_C32_SINT32: + case TIFF_SETGET_C32_FLOAT: + case TIFF_SETGET_C32_UINT64: + case TIFF_SETGET_C32_SINT64: + case TIFF_SETGET_C32_DOUBLE: + case TIFF_SETGET_C32_IFD8: + return 4; + default: + return 0; + } } /*-- TIFFFieldSetGetCountSize() --- */ - -const TIFFField* -TIFFFindField(TIFF* tif, uint32_t tag, TIFFDataType dt) +const TIFFField *TIFFFindField(TIFF *tif, uint32_t tag, TIFFDataType dt) { - TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; - TIFFField* pkey = &key; - const TIFFField **ret; - if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag && - (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) - return tif->tif_foundfield; - - /* If we are invoked with no field information, then just return. */ - if (!tif->tif_fields) - return NULL; - - /* NB: use sorted search (e.g. binary search) */ - - key.field_tag = tag; - key.field_type = dt; - - ret = (const TIFFField **) bsearch(&pkey, tif->tif_fields, - tif->tif_nfields, - sizeof(TIFFField *), tagCompare); - return tif->tif_foundfield = (ret ? *ret : NULL); + TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; + TIFFField *pkey = &key; + const TIFFField **ret; + if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag && + (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) + return tif->tif_foundfield; + + /* If we are invoked with no field information, then just return. */ + if (!tif->tif_fields) + return NULL; + + /* NB: use sorted search (e.g. binary search) */ + + key.field_tag = tag; + key.field_type = dt; + + ret = (const TIFFField **)bsearch(&pkey, tif->tif_fields, tif->tif_nfields, + sizeof(TIFFField *), tagCompare); + return tif->tif_foundfield = (ret ? *ret : NULL); } -static const TIFFField* -_TIFFFindFieldByName(TIFF* tif, const char *field_name, TIFFDataType dt) +static const TIFFField *_TIFFFindFieldByName(TIFF *tif, const char *field_name, + TIFFDataType dt) { - TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; - TIFFField* pkey = &key; - const TIFFField **ret; - if (tif->tif_foundfield - && streq(tif->tif_foundfield->field_name, field_name) - && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) - return (tif->tif_foundfield); + TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL}; + TIFFField *pkey = &key; + const TIFFField **ret; + if (tif->tif_foundfield && + streq(tif->tif_foundfield->field_name, field_name) && + (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type)) + return (tif->tif_foundfield); - /* If we are invoked with no field information, then just return. */ - if (!tif->tif_fields) - return NULL; + /* If we are invoked with no field information, then just return. */ + if (!tif->tif_fields) + return NULL; - /* NB: use linear search since list is sorted by key#, not name */ + /* NB: use linear search since list is sorted by key#, not name */ - key.field_name = (char *)field_name; - key.field_type = dt; + key.field_name = (char *)field_name; + key.field_type = dt; - ret = (const TIFFField **) - td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields, - sizeof(TIFFField *), tagNameCompare); + ret = + (const TIFFField **)td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields, + sizeof(TIFFField *), tagNameCompare); - return tif->tif_foundfield = (ret ? *ret : NULL); + return tif->tif_foundfield = (ret ? *ret : NULL); } -const TIFFField* -TIFFFieldWithTag(TIFF* tif, uint32_t tag) +const TIFFField *TIFFFieldWithTag(TIFF *tif, uint32_t tag) { - const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); - if (!fip) { - TIFFErrorExtR(tif, "TIFFFieldWithTag", - "Internal error, unknown tag 0x%x", - (unsigned int) tag); - } - return (fip); + const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); + if (!fip) + { + TIFFErrorExtR(tif, "TIFFFieldWithTag", + "Internal error, unknown tag 0x%x", (unsigned int)tag); + } + return (fip); } -const TIFFField* -TIFFFieldWithName(TIFF* tif, const char *field_name) +const TIFFField *TIFFFieldWithName(TIFF *tif, const char *field_name) { - const TIFFField* fip = - _TIFFFindFieldByName(tif, field_name, TIFF_ANY); - if (!fip) { - TIFFErrorExtR(tif, "TIFFFieldWithName", - "Internal error, unknown tag %s", field_name); - } - return (fip); + const TIFFField *fip = _TIFFFindFieldByName(tif, field_name, TIFF_ANY); + if (!fip) + { + TIFFErrorExtR(tif, "TIFFFieldWithName", + "Internal error, unknown tag %s", field_name); + } + return (fip); } -uint32_t -TIFFFieldTag(const TIFFField* fip) -{ - return fip->field_tag; -} +uint32_t TIFFFieldTag(const TIFFField *fip) { return fip->field_tag; } -const char * -TIFFFieldName(const TIFFField* fip) -{ - return fip->field_name; -} +const char *TIFFFieldName(const TIFFField *fip) { return fip->field_name; } -TIFFDataType -TIFFFieldDataType(const TIFFField* fip) -{ - return fip->field_type; -} +TIFFDataType TIFFFieldDataType(const TIFFField *fip) { return fip->field_type; } -int -TIFFFieldPassCount(const TIFFField* fip) -{ - return fip->field_passcount; -} +int TIFFFieldPassCount(const TIFFField *fip) { return fip->field_passcount; } -int -TIFFFieldReadCount(const TIFFField* fip) -{ - return fip->field_readcount; -} +int TIFFFieldReadCount(const TIFFField *fip) { return fip->field_readcount; } -int -TIFFFieldWriteCount(const TIFFField* fip) -{ - return fip->field_writecount; -} +int TIFFFieldWriteCount(const TIFFField *fip) { return fip->field_writecount; } -int -TIFFFieldIsAnonymous(const TIFFField *fip) -{ - return fip->field_anonymous; -} +int TIFFFieldIsAnonymous(const TIFFField *fip) { return fip->field_anonymous; } -const TIFFField* -_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag, TIFFDataType dt) +const TIFFField *_TIFFFindOrRegisterField(TIFF *tif, uint32_t tag, + TIFFDataType dt) { - const TIFFField *fld; + const TIFFField *fld; - fld = TIFFFindField(tif, tag, dt); - if (fld == NULL) { - fld = _TIFFCreateAnonField(tif, tag, dt); - if (!_TIFFMergeFields(tif, fld, 1)) - return NULL; - } + fld = TIFFFindField(tif, tag, dt); + if (fld == NULL) + { + fld = _TIFFCreateAnonField(tif, tag, dt); + if (!_TIFFMergeFields(tif, fld, 1)) + return NULL; + } - return fld; + return fld; } -TIFFField* -_TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type) +TIFFField *_TIFFCreateAnonField(TIFF *tif, uint32_t tag, + TIFFDataType field_type) { - TIFFField *fld; - (void) tif; - - fld = (TIFFField *) _TIFFmallocExt(tif, sizeof (TIFFField)); - if (fld == NULL) - return NULL; - _TIFFmemset(fld, 0, sizeof(TIFFField)); - - fld->field_tag = tag; - fld->field_readcount = TIFF_VARIABLE2; - fld->field_writecount = TIFF_VARIABLE2; - fld->field_type = field_type; - fld->field_anonymous = 1; /* indicate that this is an anonymous / unknown tag */ - switch (field_type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - fld->set_field_type = TIFF_SETGET_C32_UINT8; - fld->get_field_type = TIFF_SETGET_C32_UINT8; - break; - case TIFF_ASCII: - fld->set_field_type = TIFF_SETGET_C32_ASCII; - fld->get_field_type = TIFF_SETGET_C32_ASCII; - break; - case TIFF_SHORT: - fld->set_field_type = TIFF_SETGET_C32_UINT16; - fld->get_field_type = TIFF_SETGET_C32_UINT16; - break; - case TIFF_LONG: - fld->set_field_type = TIFF_SETGET_C32_UINT32; - fld->get_field_type = TIFF_SETGET_C32_UINT32; - break; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - fld->set_field_type = TIFF_SETGET_C32_FLOAT; - fld->get_field_type = TIFF_SETGET_C32_FLOAT; - break; - case TIFF_SBYTE: - fld->set_field_type = TIFF_SETGET_C32_SINT8; - fld->get_field_type = TIFF_SETGET_C32_SINT8; - break; - case TIFF_SSHORT: - fld->set_field_type = TIFF_SETGET_C32_SINT16; - fld->get_field_type = TIFF_SETGET_C32_SINT16; - break; - case TIFF_SLONG: - fld->set_field_type = TIFF_SETGET_C32_SINT32; - fld->get_field_type = TIFF_SETGET_C32_SINT32; - break; - case TIFF_DOUBLE: - fld->set_field_type = TIFF_SETGET_C32_DOUBLE; - fld->get_field_type = TIFF_SETGET_C32_DOUBLE; - break; - case TIFF_IFD: - case TIFF_IFD8: - fld->set_field_type = TIFF_SETGET_C32_IFD8; - fld->get_field_type = TIFF_SETGET_C32_IFD8; - break; - case TIFF_LONG8: - fld->set_field_type = TIFF_SETGET_C32_UINT64; - fld->get_field_type = TIFF_SETGET_C32_UINT64; - break; - case TIFF_SLONG8: - fld->set_field_type = TIFF_SETGET_C32_SINT64; - fld->get_field_type = TIFF_SETGET_C32_SINT64; - break; - default: - fld->set_field_type = TIFF_SETGET_UNDEFINED; - fld->get_field_type = TIFF_SETGET_UNDEFINED; - break; - } - fld->field_bit = FIELD_CUSTOM; - fld->field_oktochange = TRUE; - fld->field_passcount = TRUE; - fld->field_name = (char *) _TIFFmallocExt(tif, 32); - if (fld->field_name == NULL) { - _TIFFfreeExt(tif, fld); - return NULL; - } - fld->field_subfields = NULL; - - /* - * note that this name is a special sign to TIFFClose() and - * _TIFFSetupFields() to free the field - * Update: - * This special sign is replaced by fld->field_anonymous flag. - */ - (void) snprintf(fld->field_name, 32, "Tag %d", (int) tag); - - return fld; + TIFFField *fld; + (void)tif; + + fld = (TIFFField *)_TIFFmallocExt(tif, sizeof(TIFFField)); + if (fld == NULL) + return NULL; + _TIFFmemset(fld, 0, sizeof(TIFFField)); + + fld->field_tag = tag; + fld->field_readcount = TIFF_VARIABLE2; + fld->field_writecount = TIFF_VARIABLE2; + fld->field_type = field_type; + fld->field_anonymous = + 1; /* indicate that this is an anonymous / unknown tag */ + switch (field_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + fld->set_field_type = TIFF_SETGET_C32_UINT8; + fld->get_field_type = TIFF_SETGET_C32_UINT8; + break; + case TIFF_ASCII: + fld->set_field_type = TIFF_SETGET_C32_ASCII; + fld->get_field_type = TIFF_SETGET_C32_ASCII; + break; + case TIFF_SHORT: + fld->set_field_type = TIFF_SETGET_C32_UINT16; + fld->get_field_type = TIFF_SETGET_C32_UINT16; + break; + case TIFF_LONG: + fld->set_field_type = TIFF_SETGET_C32_UINT32; + fld->get_field_type = TIFF_SETGET_C32_UINT32; + break; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + fld->set_field_type = TIFF_SETGET_C32_FLOAT; + fld->get_field_type = TIFF_SETGET_C32_FLOAT; + break; + case TIFF_SBYTE: + fld->set_field_type = TIFF_SETGET_C32_SINT8; + fld->get_field_type = TIFF_SETGET_C32_SINT8; + break; + case TIFF_SSHORT: + fld->set_field_type = TIFF_SETGET_C32_SINT16; + fld->get_field_type = TIFF_SETGET_C32_SINT16; + break; + case TIFF_SLONG: + fld->set_field_type = TIFF_SETGET_C32_SINT32; + fld->get_field_type = TIFF_SETGET_C32_SINT32; + break; + case TIFF_DOUBLE: + fld->set_field_type = TIFF_SETGET_C32_DOUBLE; + fld->get_field_type = TIFF_SETGET_C32_DOUBLE; + break; + case TIFF_IFD: + case TIFF_IFD8: + fld->set_field_type = TIFF_SETGET_C32_IFD8; + fld->get_field_type = TIFF_SETGET_C32_IFD8; + break; + case TIFF_LONG8: + fld->set_field_type = TIFF_SETGET_C32_UINT64; + fld->get_field_type = TIFF_SETGET_C32_UINT64; + break; + case TIFF_SLONG8: + fld->set_field_type = TIFF_SETGET_C32_SINT64; + fld->get_field_type = TIFF_SETGET_C32_SINT64; + break; + default: + fld->set_field_type = TIFF_SETGET_UNDEFINED; + fld->get_field_type = TIFF_SETGET_UNDEFINED; + break; + } + fld->field_bit = FIELD_CUSTOM; + fld->field_oktochange = TRUE; + fld->field_passcount = TRUE; + fld->field_name = (char *)_TIFFmallocExt(tif, 32); + if (fld->field_name == NULL) + { + _TIFFfreeExt(tif, fld); + return NULL; + } + fld->field_subfields = NULL; + + /* + * note that this name is a special sign to TIFFClose() and + * _TIFFSetupFields() to free the field + * Update: + * This special sign is replaced by fld->field_anonymous flag. + */ + (void)snprintf(fld->field_name, 32, "Tag %d", (int)tag); + + return fld; } /**************************************************************************** @@ -933,345 +1192,353 @@ _TIFFCreateAnonField(TIFF *tif, uint32_t tag, TIFFDataType field_type) * libtiff versions. ****************************************************************************/ -static TIFFSetGetFieldType -_TIFFSetGetType(TIFFDataType type, short count, unsigned char passcount) +static TIFFSetGetFieldType _TIFFSetGetType(TIFFDataType type, short count, + unsigned char passcount) { - if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0) - return TIFF_SETGET_ASCII; - - else if (count == 1 && passcount == 0) { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_UINT16; - case TIFF_LONG: - return TIFF_SETGET_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } - - else if (count >= 1 && passcount == 0) { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_C0_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_C0_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_C0_UINT16; - case TIFF_LONG: - return TIFF_SETGET_C0_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_C0_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_C0_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_C0_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_C0_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_C0_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_C0_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_C0_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_C0_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } - - else if (count == TIFF_VARIABLE && passcount == 1) { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_C16_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_C16_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_C16_UINT16; - case TIFF_LONG: - return TIFF_SETGET_C16_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_C16_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_C16_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_C16_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_C16_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_C16_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_C16_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_C16_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_C16_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } - - else if (count == TIFF_VARIABLE2 && passcount == 1) { - switch (type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: - return TIFF_SETGET_C32_UINT8; - case TIFF_ASCII: - return TIFF_SETGET_C32_ASCII; - case TIFF_SHORT: - return TIFF_SETGET_C32_UINT16; - case TIFF_LONG: - return TIFF_SETGET_C32_UINT32; - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - return TIFF_SETGET_C32_FLOAT; - case TIFF_SBYTE: - return TIFF_SETGET_C32_SINT8; - case TIFF_SSHORT: - return TIFF_SETGET_C32_SINT16; - case TIFF_SLONG: - return TIFF_SETGET_C32_SINT32; - case TIFF_DOUBLE: - return TIFF_SETGET_C32_DOUBLE; - case TIFF_IFD: - case TIFF_IFD8: - return TIFF_SETGET_C32_IFD8; - case TIFF_LONG8: - return TIFF_SETGET_C32_UINT64; - case TIFF_SLONG8: - return TIFF_SETGET_C32_SINT64; - default: - return TIFF_SETGET_UNDEFINED; - } - } - - return TIFF_SETGET_UNDEFINED; + if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0) + return TIFF_SETGET_ASCII; + + else if (count == 1 && passcount == 0) + { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_UINT16; + case TIFF_LONG: + return TIFF_SETGET_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + else if (count >= 1 && passcount == 0) + { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C0_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C0_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C0_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C0_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C0_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C0_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C0_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C0_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C0_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C0_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C0_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C0_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + else if (count == TIFF_VARIABLE && passcount == 1) + { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C16_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C16_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C16_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C16_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C16_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C16_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C16_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C16_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C16_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C16_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C16_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C16_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + else if (count == TIFF_VARIABLE2 && passcount == 1) + { + switch (type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: + return TIFF_SETGET_C32_UINT8; + case TIFF_ASCII: + return TIFF_SETGET_C32_ASCII; + case TIFF_SHORT: + return TIFF_SETGET_C32_UINT16; + case TIFF_LONG: + return TIFF_SETGET_C32_UINT32; + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + return TIFF_SETGET_C32_FLOAT; + case TIFF_SBYTE: + return TIFF_SETGET_C32_SINT8; + case TIFF_SSHORT: + return TIFF_SETGET_C32_SINT16; + case TIFF_SLONG: + return TIFF_SETGET_C32_SINT32; + case TIFF_DOUBLE: + return TIFF_SETGET_C32_DOUBLE; + case TIFF_IFD: + case TIFF_IFD8: + return TIFF_SETGET_C32_IFD8; + case TIFF_LONG8: + return TIFF_SETGET_C32_UINT64; + case TIFF_SLONG8: + return TIFF_SETGET_C32_SINT64; + default: + return TIFF_SETGET_UNDEFINED; + } + } + + return TIFF_SETGET_UNDEFINED; } -int -TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32_t n) +int TIFFMergeFieldInfo(TIFF *tif, const TIFFFieldInfo info[], uint32_t n) { - static const char module[] = "TIFFMergeFieldInfo"; - static const char reason[] = "for fields array"; - TIFFField *tp; - size_t nfields; - uint32_t i; - - if (tif->tif_nfieldscompat > 0) { - tif->tif_fieldscompat = (TIFFFieldArray *) - _TIFFCheckRealloc(tif, tif->tif_fieldscompat, - tif->tif_nfieldscompat + 1, - sizeof(TIFFFieldArray), reason); - } else { - tif->tif_fieldscompat = (TIFFFieldArray *) - _TIFFCheckMalloc(tif, 1, sizeof(TIFFFieldArray), - reason); - } - if (!tif->tif_fieldscompat) { - TIFFErrorExtR(tif, module, - "Failed to allocate fields array"); - return -1; - } - nfields = tif->tif_nfieldscompat++; - - tif->tif_fieldscompat[nfields].type = tfiatOther; - tif->tif_fieldscompat[nfields].allocated_size = n; - tif->tif_fieldscompat[nfields].count = n; - tif->tif_fieldscompat[nfields].fields = - (TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField), - reason); - if (!tif->tif_fieldscompat[nfields].fields) { - TIFFErrorExtR(tif, module, - "Failed to allocate fields array"); - return -1; - } - - tp = tif->tif_fieldscompat[nfields].fields; - for (i = 0; i < n; i++) { - tp->field_tag = info[i].field_tag; - tp->field_readcount = info[i].field_readcount; - tp->field_writecount = info[i].field_writecount; - tp->field_type = info[i].field_type; - tp->field_anonymous = 0; - tp->set_field_type = - _TIFFSetGetType(info[i].field_type, - info[i].field_readcount, - info[i].field_passcount); - tp->get_field_type = - _TIFFSetGetType(info[i].field_type, - info[i].field_readcount, - info[i].field_passcount); - tp->field_bit = info[i].field_bit; - tp->field_oktochange = info[i].field_oktochange; - tp->field_passcount = info[i].field_passcount; - if (info[i].field_name == NULL) { - TIFFErrorExtR(tif, module, - "Field_name of %d.th allocation tag %d is NULL", i, info[i].field_tag); - return -1; - } - tp->field_name = info[i].field_name; - tp->field_subfields = NULL; - tp++; - } - - if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) { - TIFFErrorExtR(tif, module, - "Setting up field info failed"); - return -1; - } - - return 0; + static const char module[] = "TIFFMergeFieldInfo"; + static const char reason[] = "for fields array"; + TIFFField *tp; + size_t nfields; + uint32_t i; + + if (tif->tif_nfieldscompat > 0) + { + tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckRealloc( + tif, tif->tif_fieldscompat, tif->tif_nfieldscompat + 1, + sizeof(TIFFFieldArray), reason); + } + else + { + tif->tif_fieldscompat = (TIFFFieldArray *)_TIFFCheckMalloc( + tif, 1, sizeof(TIFFFieldArray), reason); + } + if (!tif->tif_fieldscompat) + { + TIFFErrorExtR(tif, module, "Failed to allocate fields array"); + return -1; + } + nfields = tif->tif_nfieldscompat++; + + tif->tif_fieldscompat[nfields].type = tfiatOther; + tif->tif_fieldscompat[nfields].allocated_size = n; + tif->tif_fieldscompat[nfields].count = n; + tif->tif_fieldscompat[nfields].fields = + (TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField), reason); + if (!tif->tif_fieldscompat[nfields].fields) + { + TIFFErrorExtR(tif, module, "Failed to allocate fields array"); + return -1; + } + + tp = tif->tif_fieldscompat[nfields].fields; + for (i = 0; i < n; i++) + { + tp->field_tag = info[i].field_tag; + tp->field_readcount = info[i].field_readcount; + tp->field_writecount = info[i].field_writecount; + tp->field_type = info[i].field_type; + tp->field_anonymous = 0; + tp->set_field_type = + _TIFFSetGetType(info[i].field_type, info[i].field_readcount, + info[i].field_passcount); + tp->get_field_type = + _TIFFSetGetType(info[i].field_type, info[i].field_readcount, + info[i].field_passcount); + tp->field_bit = info[i].field_bit; + tp->field_oktochange = info[i].field_oktochange; + tp->field_passcount = info[i].field_passcount; + if (info[i].field_name == NULL) + { + TIFFErrorExtR(tif, module, + "Field_name of %d.th allocation tag %d is NULL", i, + info[i].field_tag); + return -1; + } + tp->field_name = info[i].field_name; + tp->field_subfields = NULL; + tp++; + } + + if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) + { + TIFFErrorExtR(tif, module, "Setting up field info failed"); + return -1; + } + + return 0; } -int -_TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) +int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag) { - /* Filter out non-codec specific tags */ - switch (tag) { - /* Shared tags */ - case TIFFTAG_PREDICTOR: - /* JPEG tags */ - case TIFFTAG_JPEGTABLES: - /* OJPEG tags */ - case TIFFTAG_JPEGIFOFFSET: - case TIFFTAG_JPEGIFBYTECOUNT: - case TIFFTAG_JPEGQTABLES: - case TIFFTAG_JPEGDCTABLES: - case TIFFTAG_JPEGACTABLES: - case TIFFTAG_JPEGPROC: - case TIFFTAG_JPEGRESTARTINTERVAL: - /* CCITT* */ - case TIFFTAG_BADFAXLINES: - case TIFFTAG_CLEANFAXDATA: - case TIFFTAG_CONSECUTIVEBADFAXLINES: - case TIFFTAG_GROUP3OPTIONS: - case TIFFTAG_GROUP4OPTIONS: - /* LERC */ - case TIFFTAG_LERC_PARAMETERS: - break; - default: - return 1; - } - if( !TIFFIsCODECConfigured(tif->tif_dir.td_compression) ) { - return 0; - } - /* Check if codec specific tags are allowed for the current - * compression scheme (codec) */ - switch (tif->tif_dir.td_compression) { - case COMPRESSION_LZW: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_PACKBITS: - /* No codec-specific tags */ - break; - case COMPRESSION_THUNDERSCAN: - /* No codec-specific tags */ - break; - case COMPRESSION_NEXT: - /* No codec-specific tags */ - break; - case COMPRESSION_JPEG: - if (tag == TIFFTAG_JPEGTABLES) - return 1; - break; - case COMPRESSION_OJPEG: - switch (tag) { - case TIFFTAG_JPEGIFOFFSET: - case TIFFTAG_JPEGIFBYTECOUNT: - case TIFFTAG_JPEGQTABLES: - case TIFFTAG_JPEGDCTABLES: - case TIFFTAG_JPEGACTABLES: - case TIFFTAG_JPEGPROC: - case TIFFTAG_JPEGRESTARTINTERVAL: - return 1; - } - break; - case COMPRESSION_CCITTRLE: - case COMPRESSION_CCITTRLEW: - case COMPRESSION_CCITTFAX3: - case COMPRESSION_CCITTFAX4: - switch (tag) { - case TIFFTAG_BADFAXLINES: - case TIFFTAG_CLEANFAXDATA: - case TIFFTAG_CONSECUTIVEBADFAXLINES: - return 1; - case TIFFTAG_GROUP3OPTIONS: - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) - return 1; - break; - case TIFFTAG_GROUP4OPTIONS: - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) - return 1; - break; - } - break; - case COMPRESSION_JBIG: - /* No codec-specific tags */ - break; - case COMPRESSION_DEFLATE: - case COMPRESSION_ADOBE_DEFLATE: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_PIXARLOG: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_SGILOG: - case COMPRESSION_SGILOG24: - /* No codec-specific tags */ - break; - case COMPRESSION_LZMA: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_ZSTD: - if (tag == TIFFTAG_PREDICTOR) - return 1; - break; - case COMPRESSION_LERC: - if (tag == TIFFTAG_LERC_PARAMETERS) - return 1; - break; - } - return 0; + /* Filter out non-codec specific tags */ + switch (tag) + { + /* Shared tags */ + case TIFFTAG_PREDICTOR: + /* JPEG tags */ + case TIFFTAG_JPEGTABLES: + /* OJPEG tags */ + case TIFFTAG_JPEGIFOFFSET: + case TIFFTAG_JPEGIFBYTECOUNT: + case TIFFTAG_JPEGQTABLES: + case TIFFTAG_JPEGDCTABLES: + case TIFFTAG_JPEGACTABLES: + case TIFFTAG_JPEGPROC: + case TIFFTAG_JPEGRESTARTINTERVAL: + /* CCITT* */ + case TIFFTAG_BADFAXLINES: + case TIFFTAG_CLEANFAXDATA: + case TIFFTAG_CONSECUTIVEBADFAXLINES: + case TIFFTAG_GROUP3OPTIONS: + case TIFFTAG_GROUP4OPTIONS: + /* LERC */ + case TIFFTAG_LERC_PARAMETERS: + break; + default: + return 1; + } + if (!TIFFIsCODECConfigured(tif->tif_dir.td_compression)) + { + return 0; + } + /* Check if codec specific tags are allowed for the current + * compression scheme (codec) */ + switch (tif->tif_dir.td_compression) + { + case COMPRESSION_LZW: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_PACKBITS: + /* No codec-specific tags */ + break; + case COMPRESSION_THUNDERSCAN: + /* No codec-specific tags */ + break; + case COMPRESSION_NEXT: + /* No codec-specific tags */ + break; + case COMPRESSION_JPEG: + if (tag == TIFFTAG_JPEGTABLES) + return 1; + break; + case COMPRESSION_OJPEG: + switch (tag) + { + case TIFFTAG_JPEGIFOFFSET: + case TIFFTAG_JPEGIFBYTECOUNT: + case TIFFTAG_JPEGQTABLES: + case TIFFTAG_JPEGDCTABLES: + case TIFFTAG_JPEGACTABLES: + case TIFFTAG_JPEGPROC: + case TIFFTAG_JPEGRESTARTINTERVAL: + return 1; + } + break; + case COMPRESSION_CCITTRLE: + case COMPRESSION_CCITTRLEW: + case COMPRESSION_CCITTFAX3: + case COMPRESSION_CCITTFAX4: + switch (tag) + { + case TIFFTAG_BADFAXLINES: + case TIFFTAG_CLEANFAXDATA: + case TIFFTAG_CONSECUTIVEBADFAXLINES: + return 1; + case TIFFTAG_GROUP3OPTIONS: + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) + return 1; + break; + case TIFFTAG_GROUP4OPTIONS: + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) + return 1; + break; + } + break; + case COMPRESSION_JBIG: + /* No codec-specific tags */ + break; + case COMPRESSION_DEFLATE: + case COMPRESSION_ADOBE_DEFLATE: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_PIXARLOG: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_SGILOG: + case COMPRESSION_SGILOG24: + /* No codec-specific tags */ + break; + case COMPRESSION_LZMA: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_ZSTD: + if (tag == TIFFTAG_PREDICTOR) + return 1; + break; + case COMPRESSION_LERC: + if (tag == TIFFTAG_LERC_PARAMETERS) + return 1; + break; + } + return 0; } diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c index f3ae3c70..87d22b16 100644 --- a/libtiff/tif_dirread.c +++ b/libtiff/tif_dirread.c @@ -40,141 +40,232 @@ #include <stdlib.h> #include <string.h> -#define FAILED_FII ((uint32_t) -1) +#define FAILED_FII ((uint32_t)-1) #ifdef HAVE_IEEEFP -# define TIFFCvtIEEEFloatToNative(tif, n, fp) -# define TIFFCvtIEEEDoubleToNative(tif, n, dp) +#define TIFFCvtIEEEFloatToNative(tif, n, fp) +#define TIFFCvtIEEEDoubleToNative(tif, n, dp) #else -extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32_t, float*); -extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32_t, double*); +extern void TIFFCvtIEEEFloatToNative(TIFF *, uint32_t, float *); +extern void TIFFCvtIEEEDoubleToNative(TIFF *, uint32_t, double *); #endif -enum TIFFReadDirEntryErr { - TIFFReadDirEntryErrOk = 0, - TIFFReadDirEntryErrCount = 1, - TIFFReadDirEntryErrType = 2, - TIFFReadDirEntryErrIo = 3, - TIFFReadDirEntryErrRange = 4, - TIFFReadDirEntryErrPsdif = 5, - TIFFReadDirEntryErrSizesan = 6, - TIFFReadDirEntryErrAlloc = 7, +enum TIFFReadDirEntryErr +{ + TIFFReadDirEntryErrOk = 0, + TIFFReadDirEntryErrCount = 1, + TIFFReadDirEntryErrType = 2, + TIFFReadDirEntryErrIo = 3, + TIFFReadDirEntryErrRange = 4, + TIFFReadDirEntryErrPsdif = 5, + TIFFReadDirEntryErrSizesan = 6, + TIFFReadDirEntryErrAlloc = 7, }; -static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8_t* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyte(TIFF * tif, TIFFDirEntry * direntry, int8_t * value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16_t* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySshort(TIFF * tif, TIFFDirEntry * direntry, int16_t * value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32_t* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong(TIFF * tif, TIFFDirEntry * direntry, int32_t * value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8(TIFF * tif, TIFFDirEntry * direntry, int64_t * value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32_t* count, uint32_t desttypesize, void** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8_t** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8_t** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16_t** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16_t** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32_t** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32_t** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64_t** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64_t** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64_t** value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16_t* value); - -static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8_t* value); -static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8_t* value); -static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16_t* value); -static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16_t* value); -static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32_t* value); -static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32_t* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64_t* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value); -static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64_t value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64_t value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64_t value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32_t value); -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value); - -static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF* tif, uint64_t offset, tmsize_t size, void* dest); -static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover); - -static void TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16_t dircount); -static TIFFDirEntry* TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16_t dircount, uint16_t tagid); -static void TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16_t tagid, uint32_t* fii); - -static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16_t dircount); -static void MissingRequired(TIFF*, const char*); -static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32_t); -static uint16_t TIFFFetchDirectory(TIFF* tif, uint64_t diroff, TIFFDirEntry** pdir, uint64_t* nextdiroff); -static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover); -static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32_t nstrips, uint64_t** lpp); -static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*); -static void ChopUpSingleUncompressedStrip(TIFF*); -static void TryChopUpUncompressedBigTiff(TIFF*); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value); + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count, + uint32_t desttypesize, void **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value); + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry, + uint16_t *value); + +static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry, + uint8_t *value); +static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry, + int8_t *value); +static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry, + uint16_t *value); +static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry, + int16_t *value); +static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry, + uint32_t *value); +static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry, + int32_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, + uint64_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, + int64_t *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry, + double *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry, + double *value); +static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry, + float *value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value); + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSbyte(int8_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteShort(uint16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSshort(int16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteLong(uint32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSlong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSlong8(int64_t value); + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value); + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSbyte(int8_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSshort(int16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortLong(uint32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSlong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSlong8(int64_t value); + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortShort(uint16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortLong(uint32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortSlong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value); + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSbyte(int8_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSshort(int16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSlong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSlong8(int64_t value); + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongLong(uint32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value); + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Slong(int32_t value); +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value); + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value); + +static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset, + tmsize_t size, void *dest); +static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err, + const char *module, const char *tagname, + int recover); + +static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount); +static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount, + uint16_t tagid); +static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid, + uint32_t *fii); + +static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount); +static void MissingRequired(TIFF *, const char *); +static int CheckDirCount(TIFF *, TIFFDirEntry *, uint32_t); +static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, + TIFFDirEntry **pdir, uint64_t *nextdiroff); +static int TIFFFetchNormalTag(TIFF *, TIFFDirEntry *, int recover); +static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips, + uint64_t **lpp); +static int TIFFFetchSubjectDistance(TIFF *, TIFFDirEntry *); +static void ChopUpSingleUncompressedStrip(TIFF *); +static void TryChopUpUncompressedBigTiff(TIFF *); static uint64_t TIFFReadUInt64(const uint8_t *value); static int _TIFFGetMaxColorChannels(uint16_t photometric); -static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount ); +static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount); typedef union _UInt64Aligned_t { - double d; - uint64_t l; - uint32_t i[2]; - uint16_t s[4]; - uint8_t c[8]; + double d; + uint64_t l; + uint32_t i[2]; + uint16_t s[4]; + uint8_t c[8]; } UInt64Aligned_t; /* @@ -182,3620 +273,3706 @@ typedef union _UInt64Aligned_t */ static uint64_t TIFFReadUInt64(const uint8_t *value) { - UInt64Aligned_t result; - - result.c[0]=value[0]; - result.c[1]=value[1]; - result.c[2]=value[2]; - result.c[3]=value[3]; - result.c[4]=value[4]; - result.c[5]=value[5]; - result.c[6]=value[6]; - result.c[7]=value[7]; - - return result.l; + UInt64Aligned_t result; + + result.c[0] = value[0]; + result.c[1] = value[1]; + result.c[2] = value[2]; + result.c[3] = value[3]; + result.c[4] = value[4]; + result.c[5] = value[5]; + result.c[6] = value[6]; + result.c[7] = value[7]; + + return result.l; } -static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8_t* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryByte(TIFF *tif, TIFFDirEntry *direntry, uint8_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with field_readcount==1 */ - TIFFReadDirEntryCheckedByte(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteSbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteShort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteSshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteLong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeByteSlong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeByteLong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeByteSlong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint8_t)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with + field_readcount==1 */ + TIFFReadDirEntryCheckedByte(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeByteSbyte(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeByteShort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeByteSshort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeByteLong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeByteSlong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeByteLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeByteSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint8_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } } -static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySbyte(TIFF *tif, TIFFDirEntry *direntry, int8_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with field_readcount==1 */ - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeSbyteByte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(int8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - TIFFReadDirEntryCheckedSbyte(tif, direntry, value); - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSbyteShort(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSbyteSshort(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSbyteLong(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSbyteSlong(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return(err); - err = TIFFReadDirEntryCheckRangeSbyteLong8(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int8_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return(err); - err = TIFFReadDirEntryCheckRangeSbyteSlong8(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int8_t)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntrySbyte() --*/ - -static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16_t* value) + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with + field_readcount==1 */ + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteByte(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + TIFFReadDirEntryCheckedSbyte(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteShort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteSshort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteLong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSbyteSlong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSbyteLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSbyteSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int8_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySbyte() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryShort(TIFF *tif, TIFFDirEntry *direntry, uint16_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(uint16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortSbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - TIFFReadDirEntryCheckedShort(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortSshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortLong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeShortSlong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeShortLong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeShortSlong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint16_t)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntryShort() --*/ - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value) + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeShortSbyte(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + TIFFReadDirEntryCheckedShort(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeShortSshort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeShortLong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeShortSlong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeShortLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeShortSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntryShort() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySshort(TIFF *tif, TIFFDirEntry *direntry, int16_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (int16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - *value = (int16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSshortShort(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (uint16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - TIFFReadDirEntryCheckedSshort(tif, direntry, value); - return(TIFFReadDirEntryErrOk); - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSshortLong(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSshortSlong(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return(err); - err = TIFFReadDirEntryCheckRangeSshortLong8(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int16_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return(err); - err = TIFFReadDirEntryCheckRangeSshortSlong8(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int16_t)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntrySshort() --*/ - - -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32_t* value) + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSshortShort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + TIFFReadDirEntryCheckedSshort(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSshortLong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSshortSlong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSshortLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSshortSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int16_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySshort() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong(TIFF *tif, TIFFDirEntry *direntry, uint32_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(uint32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLongSbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(uint32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLongSshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - TIFFReadDirEntryCheckedLong(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLongSlong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeLongLong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeLongSlong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint32_t)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntryLong() --*/ - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value) + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLongSbyte(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLongSshort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + TIFFReadDirEntryCheckedLong(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLongSlong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeLongLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeLongSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint32_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntryLong() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong(TIFF *tif, TIFFDirEntry *direntry, int32_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (int32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - *value = (int32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - *value = (int32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - *value = (int32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - err = TIFFReadDirEntryCheckRangeSlongLong(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - TIFFReadDirEntryCheckedSlong(tif, direntry, value); - return(TIFFReadDirEntryErrOk); - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return(err); - err = TIFFReadDirEntryCheckRangeSlongLong8(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int32_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return(err); - err = TIFFReadDirEntryCheckRangeSlongSlong8(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int32_t)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntrySlong() --*/ - -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value) + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeSlongLong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + TIFFReadDirEntryCheckedSlong(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSlongLong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSlongSlong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int32_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySlong() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(uint64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLong8Sbyte(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(uint64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLong8Sshort(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(uint64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - err=TIFFReadDirEntryCheckRangeLong8Slong(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - err=TIFFReadDirEntryCheckedLong8(tif,direntry,value); - return(err); - case TIFF_SLONG8: - { - int64_t m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - err=TIFFReadDirEntryCheckRangeLong8Slong8(m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(uint64_t)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntryLong8() --*/ - -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value) + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLong8Sbyte(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLong8Sshort(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + err = TIFFReadDirEntryCheckRangeLong8Slong(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + err = TIFFReadDirEntryCheckedLong8(tif, direntry, value); + return (err); + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeLong8Slong8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntryLong8() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count != 1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif, direntry, &m); - *value = (int64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); - *value = (int64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif, direntry, &m); - *value = (int64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif, direntry, &m); - *value = (int64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif, direntry, &m); - *value = (int64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif, direntry, &m); - *value = (int64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); - if (err != TIFFReadDirEntryErrOk) - return(err); - err = TIFFReadDirEntryCheckRangeSlong8Long8(m); - if (err != TIFFReadDirEntryErrOk) - return(err); - *value = (int64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - err = TIFFReadDirEntryCheckedSlong8(tif, direntry, value); - return(err); - default: - return(TIFFReadDirEntryErrType); - } -} /*-- TIFFReadDirEntrySlong8() --*/ - - -static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value) + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + err = TIFFReadDirEntryCheckRangeSlong8Long8(m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (int64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, value); + return (err); + default: + return (TIFFReadDirEntryErrType); + } +} /*-- TIFFReadDirEntrySlong8() --*/ + +static enum TIFFReadDirEntryErr +TIFFReadDirEntryFloat(TIFF *tif, TIFFDirEntry *direntry, float *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); #if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support conversion - * of 64-bit integers into floating point - * values. - */ - *value = _TIFFUInt64ToFloat(m); + /* + * XXX: MSVC 6.0 does not support conversion + * of 64-bit integers into floating point + * values. + */ + *value = _TIFFUInt64ToFloat(m); #else - *value=(float)m; + *value = (float)m; #endif - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_RATIONAL: - { - double m; - err=TIFFReadDirEntryCheckedRational(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SRATIONAL: - { - double m; - err=TIFFReadDirEntryCheckedSrational(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_FLOAT: - TIFFReadDirEntryCheckedFloat(tif,direntry,value); - return(TIFFReadDirEntryErrOk); - case TIFF_DOUBLE: - { - double m; - err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - if ((m > FLT_MAX) || (m < -FLT_MAX)) - return(TIFFReadDirEntryErrRange); - *value=(float)m; - return(TIFFReadDirEntryErrOk); - } - default: - return(TIFFReadDirEntryErrType); - } + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_RATIONAL: + { + double m; + err = TIFFReadDirEntryCheckedRational(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SRATIONAL: + { + double m; + err = TIFFReadDirEntryCheckedSrational(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_FLOAT: + TIFFReadDirEntryCheckedFloat(tif, direntry, value); + return (TIFFReadDirEntryErrOk); + case TIFF_DOUBLE: + { + double m; + err = TIFFReadDirEntryCheckedDouble(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + if ((m > FLT_MAX) || (m < -FLT_MAX)) + return (TIFFReadDirEntryErrRange); + *value = (float)m; + return (TIFFReadDirEntryErrOk); + } + default: + return (TIFFReadDirEntryErrType); + } } -static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryDouble(TIFF *tif, TIFFDirEntry *direntry, double *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t m; - TIFFReadDirEntryCheckedByte(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - { - int8_t m; - TIFFReadDirEntryCheckedSbyte(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SHORT: - { - uint16_t m; - TIFFReadDirEntryCheckedShort(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - { - int16_t m; - TIFFReadDirEntryCheckedSshort(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - { - int32_t m; - TIFFReadDirEntryCheckedSlong(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - { - uint64_t m; - err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t m; + TIFFReadDirEntryCheckedByte(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + { + int8_t m; + TIFFReadDirEntryCheckedSbyte(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SHORT: + { + uint16_t m; + TIFFReadDirEntryCheckedShort(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + { + int16_t m; + TIFFReadDirEntryCheckedSshort(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + { + int32_t m; + TIFFReadDirEntryCheckedSlong(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + { + uint64_t m; + err = TIFFReadDirEntryCheckedLong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); #if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support conversion - * of 64-bit integers into floating point - * values. - */ - *value = _TIFFUInt64ToDouble(m); + /* + * XXX: MSVC 6.0 does not support conversion + * of 64-bit integers into floating point + * values. + */ + *value = _TIFFUInt64ToDouble(m); #else - *value = (double)m; + *value = (double)m; #endif - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - { - int64_t m; - err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk) - return(err); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_RATIONAL: - err=TIFFReadDirEntryCheckedRational(tif,direntry,value); - return(err); - case TIFF_SRATIONAL: - err=TIFFReadDirEntryCheckedSrational(tif,direntry,value); - return(err); - case TIFF_FLOAT: - { - float m; - TIFFReadDirEntryCheckedFloat(tif,direntry,&m); - *value=(double)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_DOUBLE: - err=TIFFReadDirEntryCheckedDouble(tif,direntry,value); - return(err); - default: - return(TIFFReadDirEntryErrType); - } + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + { + int64_t m; + err = TIFFReadDirEntryCheckedSlong8(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk) + return (err); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_RATIONAL: + err = TIFFReadDirEntryCheckedRational(tif, direntry, value); + return (err); + case TIFF_SRATIONAL: + err = TIFFReadDirEntryCheckedSrational(tif, direntry, value); + return (err); + case TIFF_FLOAT: + { + float m; + TIFFReadDirEntryCheckedFloat(tif, direntry, &m); + *value = (double)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_DOUBLE: + err = TIFFReadDirEntryCheckedDouble(tif, direntry, value); + return (err); + default: + return (TIFFReadDirEntryErrType); + } } -static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryIfd8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) { - enum TIFFReadDirEntryErr err; - if (direntry->tdir_count!=1) - return(TIFFReadDirEntryErrCount); - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_IFD: - { - uint32_t m; - TIFFReadDirEntryCheckedLong(tif,direntry,&m); - *value=(uint64_t)m; - return(TIFFReadDirEntryErrOk); - } - case TIFF_LONG8: - case TIFF_IFD8: - err=TIFFReadDirEntryCheckedLong8(tif,direntry,value); - return(err); - default: - return(TIFFReadDirEntryErrType); - } + enum TIFFReadDirEntryErr err; + if (direntry->tdir_count != 1) + return (TIFFReadDirEntryErrCount); + switch (direntry->tdir_type) + { + case TIFF_LONG: + case TIFF_IFD: + { + uint32_t m; + TIFFReadDirEntryCheckedLong(tif, direntry, &m); + *value = (uint64_t)m; + return (TIFFReadDirEntryErrOk); + } + case TIFF_LONG8: + case TIFF_IFD8: + err = TIFFReadDirEntryCheckedLong8(tif, direntry, value); + return (err); + default: + return (TIFFReadDirEntryErrType); + } } - #define INITIAL_THRESHOLD (1024 * 1024) #define THRESHOLD_MULTIPLIER 10 -#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD) - -static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc( - TIFF* tif, uint64_t offset, tmsize_t size, void** pdest) +#define MAX_THRESHOLD \ + (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \ + INITIAL_THRESHOLD) + +static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(TIFF *tif, + uint64_t offset, + tmsize_t size, + void **pdest) { #if SIZEOF_SIZE_T == 8 - tmsize_t threshold = INITIAL_THRESHOLD; + tmsize_t threshold = INITIAL_THRESHOLD; #endif - tmsize_t already_read = 0; + tmsize_t already_read = 0; - assert( !isMapped(tif) ); + assert(!isMapped(tif)); - if (!SeekOK(tif,offset)) - return(TIFFReadDirEntryErrIo); + if (!SeekOK(tif, offset)) + return (TIFFReadDirEntryErrIo); - /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ - /* so as to avoid allocating too much memory in case the file is too */ - /* short. We could ask for the file size, but this might be */ - /* expensive with some I/O layers (think of reading a gzipped file) */ - /* Restrict to 64 bit processes, so as to avoid reallocs() */ - /* on 32 bit processes where virtual memory is scarce. */ - while( already_read < size ) - { - void* new_dest; - tmsize_t bytes_read; - tmsize_t to_read = size - already_read; + /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ + /* so as to avoid allocating too much memory in case the file is too */ + /* short. We could ask for the file size, but this might be */ + /* expensive with some I/O layers (think of reading a gzipped file) */ + /* Restrict to 64 bit processes, so as to avoid reallocs() */ + /* on 32 bit processes where virtual memory is scarce. */ + while (already_read < size) + { + void *new_dest; + tmsize_t bytes_read; + tmsize_t to_read = size - already_read; #if SIZEOF_SIZE_T == 8 - if( to_read >= threshold && threshold < MAX_THRESHOLD ) - { - to_read = threshold; - threshold *= THRESHOLD_MULTIPLIER; - } + if (to_read >= threshold && threshold < MAX_THRESHOLD) + { + to_read = threshold; + threshold *= THRESHOLD_MULTIPLIER; + } #endif - new_dest = (uint8_t*) _TIFFreallocExt(tif, - *pdest, already_read + to_read); - if( new_dest == NULL ) - { - TIFFErrorExtR(tif, tif->tif_name, - "Failed to allocate memory for %s " - "(%"TIFF_SSIZE_FORMAT" elements of %"TIFF_SSIZE_FORMAT" bytes each)", - "TIFFReadDirEntryArray", - (tmsize_t) 1, already_read + to_read); - return TIFFReadDirEntryErrAlloc; - } - *pdest = new_dest; + new_dest = + (uint8_t *)_TIFFreallocExt(tif, *pdest, already_read + to_read); + if (new_dest == NULL) + { + TIFFErrorExtR(tif, tif->tif_name, + "Failed to allocate memory for %s " + "(%" TIFF_SSIZE_FORMAT + " elements of %" TIFF_SSIZE_FORMAT " bytes each)", + "TIFFReadDirEntryArray", (tmsize_t)1, + already_read + to_read); + return TIFFReadDirEntryErrAlloc; + } + *pdest = new_dest; - bytes_read = TIFFReadFile(tif, - (char*)*pdest + already_read, to_read); - already_read += bytes_read; - if (bytes_read != to_read) { - return TIFFReadDirEntryErrIo; - } + bytes_read = TIFFReadFile(tif, (char *)*pdest + already_read, to_read); + already_read += bytes_read; + if (bytes_read != to_read) + { + return TIFFReadDirEntryErrIo; } - return TIFFReadDirEntryErrOk; + } + return TIFFReadDirEntryErrOk; } -/* Caution: if raising that value, make sure int32 / uint32 overflows can't occur - * elsewhere */ -#define MAX_SIZE_TAG_DATA 2147483647U +/* Caution: if raising that value, make sure int32 / uint32 overflows can't + * occur elsewhere */ +#define MAX_SIZE_TAG_DATA 2147483647U -static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit( - TIFF* tif, TIFFDirEntry* direntry, uint32_t* count, uint32_t desttypesize, - void** value, uint64_t maxcount) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, + uint32_t *count, uint32_t desttypesize, + void **value, uint64_t maxcount) { - int typesize; - uint32_t datasize; - void* data; - uint64_t target_count64; - int original_datasize_clamped; - typesize=TIFFDataWidth(direntry->tdir_type); - - target_count64 = (direntry->tdir_count > maxcount) ? - maxcount : direntry->tdir_count; - - if ((target_count64==0)||(typesize==0)) - { - *value=0; - return(TIFFReadDirEntryErrOk); - } - (void) desttypesize; - - /* We just want to know if the original tag size is more than 4 bytes - * (classic TIFF) or 8 bytes (BigTIFF) - */ - original_datasize_clamped = - ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) * typesize; + int typesize; + uint32_t datasize; + void *data; + uint64_t target_count64; + int original_datasize_clamped; + typesize = TIFFDataWidth(direntry->tdir_type); - /* - * As a sanity check, make sure we have no more than a 2GB tag array - * in either the current data type or the dest data type. This also - * avoids problems with overflow of tmsize_t on 32bit systems. - */ - if ((uint64_t)(MAX_SIZE_TAG_DATA / typesize) < target_count64) - return(TIFFReadDirEntryErrSizesan); - if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64) - return(TIFFReadDirEntryErrSizesan); - - *count=(uint32_t)target_count64; - datasize=(*count)*typesize; - assert((tmsize_t)datasize>0); - - if( isMapped(tif) && datasize > (uint64_t)tif->tif_size ) - return TIFFReadDirEntryErrIo; - - if( !isMapped(tif) && - (((tif->tif_flags&TIFF_BIGTIFF) && datasize > 8) || - (!(tif->tif_flags&TIFF_BIGTIFF) && datasize > 4)) ) - { - data = NULL; - } - else - { - data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); - if (data==0) - return(TIFFReadDirEntryErrAlloc); - } - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - /* Only the condition on original_datasize_clamped. The second - * one is implied, but Coverity Scan cannot see it. */ - if (original_datasize_clamped<=4 && datasize <= 4 ) - _TIFFmemcpy(data,&direntry->tdir_offset,datasize); - else - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - if( isMapped(tif) ) - err=TIFFReadDirEntryData(tif, (uint64_t)offset, (tmsize_t)datasize, data); - else - err=TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset, (tmsize_t)datasize, &data); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return(err); - } - } - } - else - { - /* See above comment for the Classic TIFF case */ - if (original_datasize_clamped<=8 && datasize <= 8 ) - _TIFFmemcpy(data,&direntry->tdir_offset,datasize); - else - { - enum TIFFReadDirEntryErr err; - uint64_t offset = direntry->tdir_offset.toff_long8; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(&offset); - if( isMapped(tif) ) - err=TIFFReadDirEntryData(tif, (uint64_t)offset, (tmsize_t)datasize, data); - else - err=TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset, (tmsize_t)datasize, &data); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return(err); - } - } - } - *value=data; - return(TIFFReadDirEntryErrOk); + target_count64 = + (direntry->tdir_count > maxcount) ? maxcount : direntry->tdir_count; + + if ((target_count64 == 0) || (typesize == 0)) + { + *value = 0; + return (TIFFReadDirEntryErrOk); + } + (void)desttypesize; + + /* We just want to know if the original tag size is more than 4 bytes + * (classic TIFF) or 8 bytes (BigTIFF) + */ + original_datasize_clamped = + ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) * + typesize; + + /* + * As a sanity check, make sure we have no more than a 2GB tag array + * in either the current data type or the dest data type. This also + * avoids problems with overflow of tmsize_t on 32bit systems. + */ + if ((uint64_t)(MAX_SIZE_TAG_DATA / typesize) < target_count64) + return (TIFFReadDirEntryErrSizesan); + if ((uint64_t)(MAX_SIZE_TAG_DATA / desttypesize) < target_count64) + return (TIFFReadDirEntryErrSizesan); + + *count = (uint32_t)target_count64; + datasize = (*count) * typesize; + assert((tmsize_t)datasize > 0); + + if (isMapped(tif) && datasize > (uint64_t)tif->tif_size) + return TIFFReadDirEntryErrIo; + + if (!isMapped(tif) && (((tif->tif_flags & TIFF_BIGTIFF) && datasize > 8) || + (!(tif->tif_flags & TIFF_BIGTIFF) && datasize > 4))) + { + data = NULL; + } + else + { + data = _TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray"); + if (data == 0) + return (TIFFReadDirEntryErrAlloc); + } + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + /* Only the condition on original_datasize_clamped. The second + * one is implied, but Coverity Scan cannot see it. */ + if (original_datasize_clamped <= 4 && datasize <= 4) + _TIFFmemcpy(data, &direntry->tdir_offset, datasize); + else + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + if (isMapped(tif)) + err = TIFFReadDirEntryData(tif, (uint64_t)offset, + (tmsize_t)datasize, data); + else + err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset, + (tmsize_t)datasize, &data); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + } + } + else + { + /* See above comment for the Classic TIFF case */ + if (original_datasize_clamped <= 8 && datasize <= 8) + _TIFFmemcpy(data, &direntry->tdir_offset, datasize); + else + { + enum TIFFReadDirEntryErr err; + uint64_t offset = direntry->tdir_offset.toff_long8; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&offset); + if (isMapped(tif)) + err = TIFFReadDirEntryData(tif, (uint64_t)offset, + (tmsize_t)datasize, data); + else + err = TIFFReadDirEntryDataAndRealloc(tif, (uint64_t)offset, + (tmsize_t)datasize, &data); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + } + } + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32_t* count, uint32_t desttypesize, void** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t *count, + uint32_t desttypesize, void **value) { - return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, - desttypesize, value, ~((uint64_t)0)); + return TIFFReadDirEntryArrayWithLimit(tif, direntry, count, desttypesize, + value, ~((uint64_t)0)); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8_t** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryByteArray(TIFF *tif, TIFFDirEntry *direntry, uint8_t **value) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - uint8_t* data; - switch (direntry->tdir_type) - { - case TIFF_ASCII: - case TIFF_UNDEFINED: - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_ASCII: - case TIFF_UNDEFINED: - case TIFF_BYTE: - *value=(uint8_t*)origdata; - return(TIFFReadDirEntryErrOk); - case TIFF_SBYTE: - { - int8_t* m; - uint32_t n; - m=(int8_t*)origdata; - for (n=0; n<count; n++) - { - err=TIFFReadDirEntryCheckRangeByteSbyte(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return(err); - } - m++; - } - *value=(uint8_t*)origdata; - return(TIFFReadDirEntryErrOk); - } - } - data=(uint8_t*)_TIFFmallocExt(tif, count); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_SHORT: - { - uint16_t* ma; - uint8_t* mb; - uint32_t n; - ma=(uint16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - err=TIFFReadDirEntryCheckRangeByteShort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t* ma; - uint8_t* mb; - uint32_t n; - ma=(int16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)ma); - err=TIFFReadDirEntryCheckRangeByteSshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8_t)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t* ma; - uint8_t* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeByteLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t* ma; - uint8_t* mb; - uint32_t n; - ma=(int32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)ma); - err=TIFFReadDirEntryCheckRangeByteSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t* ma; - uint8_t* mb; - uint32_t n; - ma=(uint64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeByteLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t* ma; - uint8_t* mb; - uint32_t n; - ma=(int64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)ma); - err=TIFFReadDirEntryCheckRangeByteSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint8_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + uint8_t *data; + switch (direntry->tdir_type) + { + case TIFF_ASCII: + case TIFF_UNDEFINED: + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_ASCII: + case TIFF_UNDEFINED: + case TIFF_BYTE: + *value = (uint8_t *)origdata; + return (TIFFReadDirEntryErrOk); + case TIFF_SBYTE: + { + int8_t *m; + uint32_t n; + m = (int8_t *)origdata; + for (n = 0; n < count; n++) + { + err = TIFFReadDirEntryCheckRangeByteSbyte(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (uint8_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + } + data = (uint8_t *)_TIFFmallocExt(tif, count); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + { + uint16_t *ma; + uint8_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + err = TIFFReadDirEntryCheckRangeByteShort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + uint8_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + err = TIFFReadDirEntryCheckRangeByteSshort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + uint8_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + err = TIFFReadDirEntryCheckRangeByteLong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + uint8_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + err = TIFFReadDirEntryCheckRangeByteSlong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + uint8_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeByteLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + uint8_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeByteSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint8_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8_t** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySbyteArray(TIFF *tif, TIFFDirEntry *direntry, int8_t **value) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - int8_t* data; - switch (direntry->tdir_type) - { - case TIFF_UNDEFINED: - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_UNDEFINED: - case TIFF_BYTE: - { - uint8_t* m; - uint32_t n; - m=(uint8_t*)origdata; - for (n=0; n<count; n++) - { - err=TIFFReadDirEntryCheckRangeSbyteByte(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return(err); - } - m++; - } - *value=(int8_t*)origdata; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SBYTE: - *value=(int8_t*)origdata; - return(TIFFReadDirEntryErrOk); - } - data=(int8_t*)_TIFFmallocExt(tif, count); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_SHORT: - { - uint16_t* ma; - int8_t* mb; - uint32_t n; - ma=(uint16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - err=TIFFReadDirEntryCheckRangeSbyteShort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t* ma; - int8_t* mb; - uint32_t n; - ma=(int16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)ma); - err=TIFFReadDirEntryCheckRangeSbyteSshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8_t)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t* ma; - int8_t* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeSbyteLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t* ma; - int8_t* mb; - uint32_t n; - ma=(int32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)ma); - err=TIFFReadDirEntryCheckRangeSbyteSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t* ma; - int8_t* mb; - uint32_t n; - ma=(uint64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeSbyteLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t* ma; - int8_t* mb; - uint32_t n; - ma=(int64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)ma); - err=TIFFReadDirEntryCheckRangeSbyteSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int8_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + int8_t *data; + switch (direntry->tdir_type) + { + case TIFF_UNDEFINED: + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 1, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_UNDEFINED: + case TIFF_BYTE: + { + uint8_t *m; + uint32_t n; + m = (uint8_t *)origdata; + for (n = 0; n < count; n++) + { + err = TIFFReadDirEntryCheckRangeSbyteByte(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (int8_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SBYTE: + *value = (int8_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + data = (int8_t *)_TIFFmallocExt(tif, count); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + { + uint16_t *ma; + int8_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + err = TIFFReadDirEntryCheckRangeSbyteShort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + int8_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + err = TIFFReadDirEntryCheckRangeSbyteSshort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + int8_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + err = TIFFReadDirEntryCheckRangeSbyteLong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + int8_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + err = TIFFReadDirEntryCheckRangeSbyteSlong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + int8_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeSbyteLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + int8_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeSbyteSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int8_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16_t** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryShortArray(TIFF *tif, TIFFDirEntry *direntry, uint16_t **value) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - uint16_t* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_SHORT: - *value=(uint16_t*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfShort(*value,count); - return(TIFFReadDirEntryErrOk); - case TIFF_SSHORT: - { - int16_t* m; - uint32_t n; - m=(int16_t*)origdata; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)m); - err=TIFFReadDirEntryCheckRangeShortSshort(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return(err); - } - m++; - } - *value=(uint16_t*)origdata; - return(TIFFReadDirEntryErrOk); - } - } - data=(uint16_t*)_TIFFmallocExt(tif, count * 2); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t* ma; - uint16_t* mb; - uint32_t n; - ma=(uint8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(uint16_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t* ma; - uint16_t* mb; - uint32_t n; - ma=(int8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - err=TIFFReadDirEntryCheckRangeShortSbyte(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16_t)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t* ma; - uint16_t* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeShortLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t* ma; - uint16_t* mb; - uint32_t n; - ma=(int32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)ma); - err=TIFFReadDirEntryCheckRangeShortSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t* ma; - uint16_t* mb; - uint32_t n; - ma=(uint64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeShortLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t* ma; - uint16_t* mb; - uint32_t n; - ma=(int64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)ma); - err=TIFFReadDirEntryCheckRangeShortSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint16_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + uint16_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + *value = (uint16_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort(*value, count); + return (TIFFReadDirEntryErrOk); + case TIFF_SSHORT: + { + int16_t *m; + uint32_t n; + m = (int16_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)m); + err = TIFFReadDirEntryCheckRangeShortSshort(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (uint16_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + } + data = (uint16_t *)_TIFFmallocExt(tif, count * 2); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + uint16_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (uint16_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + uint16_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + err = TIFFReadDirEntryCheckRangeShortSbyte(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint16_t)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + uint16_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + err = TIFFReadDirEntryCheckRangeShortLong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint16_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + uint16_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + err = TIFFReadDirEntryCheckRangeShortSlong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint16_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + uint16_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeShortLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint16_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + uint16_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeShortSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint16_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16_t** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySshortArray(TIFF *tif, TIFFDirEntry *direntry, int16_t **value) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - int16_t* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_SHORT: - { - uint16_t* m; - uint32_t n; - m=(uint16_t*)origdata; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(m); - err=TIFFReadDirEntryCheckRangeSshortShort(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return(err); - } - m++; - } - *value=(int16_t*)origdata; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SSHORT: - *value=(int16_t*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfShort((uint16_t*)(*value), count); - return(TIFFReadDirEntryErrOk); - } - data=(int16_t*)_TIFFmallocExt(tif, count * 2); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t* ma; - int16_t* mb; - uint32_t n; - ma=(uint8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(int16_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t* ma; - int16_t* mb; - uint32_t n; - ma=(int8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(int16_t)(*ma++); - } - break; - case TIFF_LONG: - { - uint32_t* ma; - int16_t* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - err=TIFFReadDirEntryCheckRangeSshortLong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t* ma; - int16_t* mb; - uint32_t n; - ma=(int32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)ma); - err=TIFFReadDirEntryCheckRangeSshortSlong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t* ma; - int16_t* mb; - uint32_t n; - ma=(uint64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeSshortLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t* ma; - int16_t* mb; - uint32_t n; - ma=(int64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)ma); - err=TIFFReadDirEntryCheckRangeSshortSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int16_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + int16_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 2, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_SHORT: + { + uint16_t *m; + uint32_t n; + m = (uint16_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(m); + err = TIFFReadDirEntryCheckRangeSshortShort(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (int16_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SSHORT: + *value = (int16_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort((uint16_t *)(*value), count); + return (TIFFReadDirEntryErrOk); + } + data = (int16_t *)_TIFFmallocExt(tif, count * 2); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + int16_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int16_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + int16_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int16_t)(*ma++); + } + break; + case TIFF_LONG: + { + uint32_t *ma; + int16_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + err = TIFFReadDirEntryCheckRangeSshortLong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int16_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + int16_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + err = TIFFReadDirEntryCheckRangeSshortSlong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int16_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + int16_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeSshortLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int16_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + int16_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeSshortSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int16_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32_t** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLongArray(TIFF *tif, TIFFDirEntry *direntry, uint32_t **value) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - uint32_t* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG: - *value=(uint32_t*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(*value,count); - return(TIFFReadDirEntryErrOk); - case TIFF_SLONG: - { - int32_t* m; - uint32_t n; - m=(int32_t*)origdata; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)m); - err=TIFFReadDirEntryCheckRangeLongSlong(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return(err); - } - m++; - } - *value=(uint32_t*)origdata; - return(TIFFReadDirEntryErrOk); - } - } - data=(uint32_t*)_TIFFmallocExt(tif, count * 4); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t* ma; - uint32_t* mb; - uint32_t n; - ma=(uint8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(uint32_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t* ma; - uint32_t* mb; - uint32_t n; - ma=(int8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - err=TIFFReadDirEntryCheckRangeLongSbyte(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint32_t)(*ma++); - } - } - break; - case TIFF_SHORT: - { - uint16_t* ma; - uint32_t* mb; - uint32_t n; - ma=(uint16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(uint32_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t* ma; - uint32_t* mb; - uint32_t n; - ma=(int16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)ma); - err=TIFFReadDirEntryCheckRangeLongSshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint32_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t* ma; - uint32_t* mb; - uint32_t n; - ma=(uint64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeLongLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint32_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t* ma; - uint32_t* mb; - uint32_t n; - ma=(int64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)ma); - err=TIFFReadDirEntryCheckRangeLongSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint32_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + uint32_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + *value = (uint32_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(*value, count); + return (TIFFReadDirEntryErrOk); + case TIFF_SLONG: + { + int32_t *m; + uint32_t n; + m = (int32_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)m); + err = TIFFReadDirEntryCheckRangeLongSlong(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (uint32_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + } + data = (uint32_t *)_TIFFmallocExt(tif, count * 4); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + uint32_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (uint32_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + uint32_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + err = TIFFReadDirEntryCheckRangeLongSbyte(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint32_t)(*ma++); + } + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + uint32_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (uint32_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + uint32_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + err = TIFFReadDirEntryCheckRangeLongSshort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint32_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + uint32_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeLongLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint32_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + uint32_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeLongSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint32_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32_t** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlongArray(TIFF *tif, TIFFDirEntry *direntry, int32_t **value) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - int32_t* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG: - { - uint32_t* m; - uint32_t n; - m=(uint32_t*)origdata; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)m); - err=TIFFReadDirEntryCheckRangeSlongLong(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return(err); - } - m++; - } - *value=(int32_t*)origdata; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG: - *value=(int32_t*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t*)(*value), count); - return(TIFFReadDirEntryErrOk); - } - data=(int32_t*)_TIFFmallocExt(tif, count * 4); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t* ma; - int32_t* mb; - uint32_t n; - ma=(uint8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(int32_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t* ma; - int32_t* mb; - uint32_t n; - ma=(int8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(int32_t)(*ma++); - } - break; - case TIFF_SHORT: - { - uint16_t* ma; - int32_t* mb; - uint32_t n; - ma=(uint16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(int32_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t* ma; - int32_t* mb; - uint32_t n; - ma=(int16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)ma); - *mb++=(int32_t)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t* ma; - int32_t* mb; - uint32_t n; - ma=(uint64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); - err=TIFFReadDirEntryCheckRangeSlongLong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int32_t)(*ma++); - } - } - break; - case TIFF_SLONG8: - { - int64_t* ma; - int32_t* mb; - uint32_t n; - ma=(int64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)ma); - err=TIFFReadDirEntryCheckRangeSlongSlong8(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(int32_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + int32_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + { + uint32_t *m; + uint32_t n; + m = (uint32_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)m); + err = TIFFReadDirEntryCheckRangeSlongLong(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (int32_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG: + *value = (int32_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)(*value), count); + return (TIFFReadDirEntryErrOk); + } + data = (int32_t *)_TIFFmallocExt(tif, count * 4); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + int32_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int32_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + int32_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int32_t)(*ma++); + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + int32_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (int32_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + int32_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + *mb++ = (int32_t)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + int32_t *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); + err = TIFFReadDirEntryCheckRangeSlongLong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int32_t)(*ma++); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + int32_t *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + err = TIFFReadDirEntryCheckRangeSlongSlong8(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (int32_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8ArrayWithLimit( - TIFF* tif, TIFFDirEntry* direntry, uint64_t** value, uint64_t maxcount) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong8ArrayWithLimit(TIFF *tif, TIFFDirEntry *direntry, + uint64_t **value, uint64_t maxcount) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - uint64_t* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArrayWithLimit(tif,direntry,&count,8,&origdata,maxcount); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG8: - *value=(uint64_t*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8(*value,count); - return(TIFFReadDirEntryErrOk); - case TIFF_SLONG8: - { - int64_t* m; - uint32_t n; - m=(int64_t*)origdata; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)m); - err=TIFFReadDirEntryCheckRangeLong8Slong8(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return(err); - } - m++; - } - *value=(uint64_t*)origdata; - return(TIFFReadDirEntryErrOk); - } - } - data=(uint64_t*)_TIFFmallocExt(tif, count * 8); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t* ma; - uint64_t* mb; - uint32_t n; - ma=(uint8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(uint64_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t* ma; - uint64_t* mb; - uint32_t n; - ma=(int8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - err=TIFFReadDirEntryCheckRangeLong8Sbyte(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint64_t)(*ma++); - } - } - break; - case TIFF_SHORT: - { - uint16_t* ma; - uint64_t* mb; - uint32_t n; - ma=(uint16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(uint64_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t* ma; - uint64_t* mb; - uint32_t n; - ma=(int16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)ma); - err=TIFFReadDirEntryCheckRangeLong8Sshort(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint64_t)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t* ma; - uint64_t* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(uint64_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t* ma; - uint64_t* mb; - uint32_t n; - ma=(int32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)ma); - err=TIFFReadDirEntryCheckRangeLong8Slong(*ma); - if (err!=TIFFReadDirEntryErrOk) - break; - *mb++=(uint64_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, data); - return(err); - } - *value=data; - return(TIFFReadDirEntryErrOk); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + uint64_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArrayWithLimit(tif, direntry, &count, 8, &origdata, + maxcount); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + *value = (uint64_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8(*value, count); + return (TIFFReadDirEntryErrOk); + case TIFF_SLONG8: + { + int64_t *m; + uint32_t n; + m = (int64_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)m); + err = TIFFReadDirEntryCheckRangeLong8Slong8(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (uint64_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + } + data = (uint64_t *)_TIFFmallocExt(tif, count * 8); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + uint64_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (uint64_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + uint64_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + err = TIFFReadDirEntryCheckRangeLong8Sbyte(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint64_t)(*ma++); + } + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + uint64_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (uint64_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + uint64_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + err = TIFFReadDirEntryCheckRangeLong8Sshort(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint64_t)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + uint64_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + *mb++ = (uint64_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + uint64_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + err = TIFFReadDirEntryCheckRangeLong8Slong(*ma); + if (err != TIFFReadDirEntryErrOk) + break; + *mb++ = (uint64_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, data); + return (err); + } + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64_t** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryLong8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value) { - return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, ~((uint64_t)0)); + return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, + ~((uint64_t)0)); } -static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64_t** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntrySlong8Array(TIFF *tif, TIFFDirEntry *direntry, int64_t **value) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - int64_t* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG8: - { - uint64_t* m; - uint32_t n; - m=(uint64_t*)origdata; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(m); - err=TIFFReadDirEntryCheckRangeSlong8Long8(*m); - if (err!=TIFFReadDirEntryErrOk) - { - _TIFFfreeExt(tif, origdata); - return(err); - } - m++; - } - *value=(int64_t*)origdata; - return(TIFFReadDirEntryErrOk); - } - case TIFF_SLONG8: - *value=(int64_t*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64_t*)(*value), count); - return(TIFFReadDirEntryErrOk); - } - data=(int64_t*)_TIFFmallocExt(tif, count * 8); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t* ma; - int64_t* mb; - uint32_t n; - ma=(uint8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(int64_t)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t* ma; - int64_t* mb; - uint32_t n; - ma=(int8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(int64_t)(*ma++); - } - break; - case TIFF_SHORT: - { - uint16_t* ma; - int64_t* mb; - uint32_t n; - ma=(uint16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(int64_t)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t* ma; - int64_t* mb; - uint32_t n; - ma=(int16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)ma); - *mb++=(int64_t)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t* ma; - int64_t* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(int64_t)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t* ma; - int64_t* mb; - uint32_t n; - ma=(int32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)ma); - *mb++=(int64_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - *value=data; - return(TIFFReadDirEntryErrOk); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + int64_t *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + { + uint64_t *m; + uint32_t n; + m = (uint64_t *)origdata; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(m); + err = TIFFReadDirEntryCheckRangeSlong8Long8(*m); + if (err != TIFFReadDirEntryErrOk) + { + _TIFFfreeExt(tif, origdata); + return (err); + } + m++; + } + *value = (int64_t *)origdata; + return (TIFFReadDirEntryErrOk); + } + case TIFF_SLONG8: + *value = (int64_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64_t *)(*value), count); + return (TIFFReadDirEntryErrOk); + } + data = (int64_t *)_TIFFmallocExt(tif, count * 8); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + int64_t *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int64_t)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + int64_t *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (int64_t)(*ma++); + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + int64_t *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (int64_t)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + int64_t *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + *mb++ = (int64_t)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + int64_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + *mb++ = (int64_t)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + int64_t *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + *mb++ = (int64_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryFloatArray(TIFF *tif, TIFFDirEntry *direntry, float **value) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - float* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - case TIFF_DOUBLE: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_FLOAT: - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t*)origdata, count); - TIFFCvtIEEEDoubleToNative(tif,count,(float*)origdata); - *value=(float*)origdata; - return(TIFFReadDirEntryErrOk); - } - data=(float*)_TIFFmallocExt(tif, count*sizeof(float)); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t* ma; - float* mb; - uint32_t n; - ma=(uint8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(float)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t* ma; - float* mb; - uint32_t n; - ma=(int8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(float)(*ma++); - } - break; - case TIFF_SHORT: - { - uint16_t* ma; - float* mb; - uint32_t n; - ma=(uint16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t* ma; - float* mb; - uint32_t n; - ma=(int16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t* ma; - float* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t* ma; - float* mb; - uint32_t n; - ma=(int32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t* ma; - float* mb; - uint32_t n; - ma=(uint64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + float *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + case TIFF_DOUBLE: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 4, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_FLOAT: + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)origdata, count); + TIFFCvtIEEEDoubleToNative(tif, count, (float *)origdata); + *value = (float *)origdata; + return (TIFFReadDirEntryErrOk); + } + data = (float *)_TIFFmallocExt(tif, count * sizeof(float)); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + float *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (float)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + float *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (float)(*ma++); + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + float *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (float)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + float *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + *mb++ = (float)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + float *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + *mb++ = (float)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + float *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + *mb++ = (float)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + float *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); #if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support - * conversion of 64-bit integers into - * floating point values. - */ - *mb++ = _TIFFUInt64ToFloat(*ma++); + /* + * XXX: MSVC 6.0 does not support + * conversion of 64-bit integers into + * floating point values. + */ + *mb++ = _TIFFUInt64ToFloat(*ma++); #else - *mb++ = (float)(*ma++); + *mb++ = (float)(*ma++); #endif - } - } - break; - case TIFF_SLONG8: - { - int64_t* ma; - float* mb; - uint32_t n; - ma=(int64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)ma); - *mb++=(float)(*ma++); - } - } - break; - case TIFF_RATIONAL: - { - uint32_t* ma; - uint32_t maa; - uint32_t mab; - float* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - maa=*ma++; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - mab=*ma++; - if (mab==0) - *mb++=0.0; - else - *mb++=(float)maa/(float)mab; - } - } - break; - case TIFF_SRATIONAL: - { - uint32_t* ma; - int32_t maa; - uint32_t mab; - float* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - maa=*(int32_t*)ma; - ma++; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - mab=*ma++; - if (mab==0) - *mb++=0.0; - else - *mb++=(float)maa/(float)mab; - } - } - break; - case TIFF_DOUBLE: - { - double* ma; - float* mb; - uint32_t n; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64_t*)origdata, count); - TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata); - ma=(double*)origdata; - mb=data; - for (n=0; n<count; n++) - { - double val = *ma++; - if( val > FLT_MAX ) - val = FLT_MAX; - else if( val < -FLT_MAX ) - val = -FLT_MAX; - *mb++=(float)val; - } - } - break; - } - _TIFFfreeExt(tif, origdata); - *value=data; - return(TIFFReadDirEntryErrOk); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + float *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + *mb++ = (float)(*ma++); + } + } + break; + case TIFF_RATIONAL: + { + uint32_t *ma; + uint32_t maa; + uint32_t mab; + float *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + maa = *ma++; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + mab = *ma++; + if (mab == 0) + *mb++ = 0.0; + else + *mb++ = (float)maa / (float)mab; + } + } + break; + case TIFF_SRATIONAL: + { + uint32_t *ma; + int32_t maa; + uint32_t mab; + float *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + maa = *(int32_t *)ma; + ma++; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + mab = *ma++; + if (mab == 0) + *mb++ = 0.0; + else + *mb++ = (float)maa / (float)mab; + } + } + break; + case TIFF_DOUBLE: + { + double *ma; + float *mb; + uint32_t n; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64_t *)origdata, count); + TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata); + ma = (double *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + double val = *ma++; + if (val > FLT_MAX) + val = FLT_MAX; + else if (val < -FLT_MAX) + val = -FLT_MAX; + *mb++ = (float)val; + } + } + break; + } + _TIFFfreeExt(tif, origdata); + *value = data; + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr -TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value) +TIFFReadDirEntryDoubleArray(TIFF *tif, TIFFDirEntry *direntry, double **value) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - double* data; - switch (direntry->tdir_type) - { - case TIFF_BYTE: - case TIFF_SBYTE: - case TIFF_SHORT: - case TIFF_SSHORT: - case TIFF_LONG: - case TIFF_SLONG: - case TIFF_LONG8: - case TIFF_SLONG8: - case TIFF_RATIONAL: - case TIFF_SRATIONAL: - case TIFF_FLOAT: - case TIFF_DOUBLE: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_DOUBLE: - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64_t*)origdata, count); - TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata); - *value=(double*)origdata; - return(TIFFReadDirEntryErrOk); - } - data=(double*)_TIFFmallocExt(tif, count*sizeof(double)); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_BYTE: - { - uint8_t* ma; - double* mb; - uint32_t n; - ma=(uint8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(double)(*ma++); - } - break; - case TIFF_SBYTE: - { - int8_t* ma; - double* mb; - uint32_t n; - ma=(int8_t*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(double)(*ma++); - } - break; - case TIFF_SHORT: - { - uint16_t* ma; - double* mb; - uint32_t n; - ma=(uint16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_SSHORT: - { - int16_t* ma; - double* mb; - uint32_t n; - ma=(int16_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_LONG: - { - uint32_t* ma; - double* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_SLONG: - { - int32_t* ma; - double* mb; - uint32_t n; - ma=(int32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_LONG8: - { - uint64_t* ma; - double* mb; - uint32_t n; - ma=(uint64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(ma); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + double *data; + switch (direntry->tdir_type) + { + case TIFF_BYTE: + case TIFF_SBYTE: + case TIFF_SHORT: + case TIFF_SSHORT: + case TIFF_LONG: + case TIFF_SLONG: + case TIFF_LONG8: + case TIFF_SLONG8: + case TIFF_RATIONAL: + case TIFF_SRATIONAL: + case TIFF_FLOAT: + case TIFF_DOUBLE: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_DOUBLE: + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64_t *)origdata, count); + TIFFCvtIEEEDoubleToNative(tif, count, (double *)origdata); + *value = (double *)origdata; + return (TIFFReadDirEntryErrOk); + } + data = (double *)_TIFFmallocExt(tif, count * sizeof(double)); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_BYTE: + { + uint8_t *ma; + double *mb; + uint32_t n; + ma = (uint8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (double)(*ma++); + } + break; + case TIFF_SBYTE: + { + int8_t *ma; + double *mb; + uint32_t n; + ma = (int8_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (double)(*ma++); + } + break; + case TIFF_SHORT: + { + uint16_t *ma; + double *mb; + uint32_t n; + ma = (uint16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(ma); + *mb++ = (double)(*ma++); + } + } + break; + case TIFF_SSHORT: + { + int16_t *ma; + double *mb; + uint32_t n; + ma = (int16_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + *mb++ = (double)(*ma++); + } + } + break; + case TIFF_LONG: + { + uint32_t *ma; + double *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + *mb++ = (double)(*ma++); + } + } + break; + case TIFF_SLONG: + { + int32_t *ma; + double *mb; + uint32_t n; + ma = (int32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + *mb++ = (double)(*ma++); + } + } + break; + case TIFF_LONG8: + { + uint64_t *ma; + double *mb; + uint32_t n; + ma = (uint64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(ma); #if defined(__WIN32__) && (_MSC_VER < 1500) - /* - * XXX: MSVC 6.0 does not support - * conversion of 64-bit integers into - * floating point values. - */ - *mb++ = _TIFFUInt64ToDouble(*ma++); + /* + * XXX: MSVC 6.0 does not support + * conversion of 64-bit integers into + * floating point values. + */ + *mb++ = _TIFFUInt64ToDouble(*ma++); #else - *mb++ = (double)(*ma++); + *mb++ = (double)(*ma++); #endif - } - } - break; - case TIFF_SLONG8: - { - int64_t* ma; - double* mb; - uint32_t n; - ma=(int64_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)ma); - *mb++=(double)(*ma++); - } - } - break; - case TIFF_RATIONAL: - { - uint32_t* ma; - uint32_t maa; - uint32_t mab; - double* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - maa=*ma++; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - mab=*ma++; - if (mab==0) - *mb++=0.0; - else - *mb++=(double)maa/(double)mab; - } - } - break; - case TIFF_SRATIONAL: - { - uint32_t* ma; - int32_t maa; - uint32_t mab; - double* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - maa=*(int32_t*)ma; - ma++; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - mab=*ma++; - if (mab==0) - *mb++=0.0; - else - *mb++=(double)maa/(double)mab; - } - } - break; - case TIFF_FLOAT: - { - float* ma; - double* mb; - uint32_t n; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t*)origdata, count); - TIFFCvtIEEEFloatToNative(tif,count,(float*)origdata); - ma=(float*)origdata; - mb=data; - for (n=0; n<count; n++) - *mb++=(double)(*ma++); - } - break; - } - _TIFFfreeExt(tif, origdata); - *value=data; - return(TIFFReadDirEntryErrOk); + } + } + break; + case TIFF_SLONG8: + { + int64_t *ma; + double *mb; + uint32_t n; + ma = (int64_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + *mb++ = (double)(*ma++); + } + } + break; + case TIFF_RATIONAL: + { + uint32_t *ma; + uint32_t maa; + uint32_t mab; + double *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + maa = *ma++; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + mab = *ma++; + if (mab == 0) + *mb++ = 0.0; + else + *mb++ = (double)maa / (double)mab; + } + } + break; + case TIFF_SRATIONAL: + { + uint32_t *ma; + int32_t maa; + uint32_t mab; + double *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + maa = *(int32_t *)ma; + ma++; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + mab = *ma++; + if (mab == 0) + *mb++ = 0.0; + else + *mb++ = (double)maa / (double)mab; + } + } + break; + case TIFF_FLOAT: + { + float *ma; + double *mb; + uint32_t n; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)origdata, count); + TIFFCvtIEEEFloatToNative(tif, count, (float *)origdata); + ma = (float *)origdata; + mb = data; + for (n = 0; n < count; n++) + *mb++ = (double)(*ma++); + } + break; + } + _TIFFfreeExt(tif, origdata); + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64_t** value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryIfd8Array(TIFF *tif, TIFFDirEntry *direntry, uint64_t **value) { - enum TIFFReadDirEntryErr err; - uint32_t count; - void* origdata; - uint64_t* data; - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_LONG8: - case TIFF_IFD: - case TIFF_IFD8: - break; - default: - return(TIFFReadDirEntryErrType); - } - err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - *value=0; - return(err); - } - switch (direntry->tdir_type) - { - case TIFF_LONG8: - case TIFF_IFD8: - *value=(uint64_t*)origdata; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8(*value,count); - return(TIFFReadDirEntryErrOk); - } - data=(uint64_t*)_TIFFmallocExt(tif, count * 8); - if (data==0) - { - _TIFFfreeExt(tif, origdata); - return(TIFFReadDirEntryErrAlloc); - } - switch (direntry->tdir_type) - { - case TIFF_LONG: - case TIFF_IFD: - { - uint32_t* ma; - uint64_t* mb; - uint32_t n; - ma=(uint32_t*)origdata; - mb=data; - for (n=0; n<count; n++) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(ma); - *mb++=(uint64_t)(*ma++); - } - } - break; - } - _TIFFfreeExt(tif, origdata); - *value=data; - return(TIFFReadDirEntryErrOk); + enum TIFFReadDirEntryErr err; + uint32_t count; + void *origdata; + uint64_t *data; + switch (direntry->tdir_type) + { + case TIFF_LONG: + case TIFF_LONG8: + case TIFF_IFD: + case TIFF_IFD8: + break; + default: + return (TIFFReadDirEntryErrType); + } + err = TIFFReadDirEntryArray(tif, direntry, &count, 8, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + *value = 0; + return (err); + } + switch (direntry->tdir_type) + { + case TIFF_LONG8: + case TIFF_IFD8: + *value = (uint64_t *)origdata; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8(*value, count); + return (TIFFReadDirEntryErrOk); + } + data = (uint64_t *)_TIFFmallocExt(tif, count * 8); + if (data == 0) + { + _TIFFfreeExt(tif, origdata); + return (TIFFReadDirEntryErrAlloc); + } + switch (direntry->tdir_type) + { + case TIFF_LONG: + case TIFF_IFD: + { + uint32_t *ma; + uint64_t *mb; + uint32_t n; + ma = (uint32_t *)origdata; + mb = data; + for (n = 0; n < count; n++) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(ma); + *mb++ = (uint64_t)(*ma++); + } + } + break; + } + _TIFFfreeExt(tif, origdata); + *value = data; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16_t* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryPersampleShort(TIFF *tif, TIFFDirEntry *direntry, + uint16_t *value) { - enum TIFFReadDirEntryErr err; - uint16_t* m; - uint16_t* na; - uint16_t nb; - if (direntry->tdir_count<(uint64_t)tif->tif_dir.td_samplesperpixel) - return(TIFFReadDirEntryErrCount); - err=TIFFReadDirEntryShortArray(tif,direntry,&m); - if (err!=TIFFReadDirEntryErrOk || m == NULL) - return(err); - na=m; - nb=tif->tif_dir.td_samplesperpixel; - *value=*na++; - nb--; - while (nb>0) - { - if (*na++!=*value) - { - err=TIFFReadDirEntryErrPsdif; - break; - } - nb--; - } - _TIFFfreeExt(tif, m); - return(err); + enum TIFFReadDirEntryErr err; + uint16_t *m; + uint16_t *na; + uint16_t nb; + if (direntry->tdir_count < (uint64_t)tif->tif_dir.td_samplesperpixel) + return (TIFFReadDirEntryErrCount); + err = TIFFReadDirEntryShortArray(tif, direntry, &m); + if (err != TIFFReadDirEntryErrOk || m == NULL) + return (err); + na = m; + nb = tif->tif_dir.td_samplesperpixel; + *value = *na++; + nb--; + while (nb > 0) + { + if (*na++ != *value) + { + err = TIFFReadDirEntryErrPsdif; + break; + } + nb--; + } + _TIFFfreeExt(tif, m); + return (err); } -static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8_t* value) +static void TIFFReadDirEntryCheckedByte(TIFF *tif, TIFFDirEntry *direntry, + uint8_t *value) { - (void) tif; - *value=*(uint8_t*)(&direntry->tdir_offset); + (void)tif; + *value = *(uint8_t *)(&direntry->tdir_offset); } -static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8_t* value) +static void TIFFReadDirEntryCheckedSbyte(TIFF *tif, TIFFDirEntry *direntry, + int8_t *value) { - (void) tif; - *value=*(int8_t*)(&direntry->tdir_offset); + (void)tif; + *value = *(int8_t *)(&direntry->tdir_offset); } -static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16_t* value) +static void TIFFReadDirEntryCheckedShort(TIFF *tif, TIFFDirEntry *direntry, + uint16_t *value) { - *value = direntry->tdir_offset.toff_short; - /* *value=*(uint16_t*)(&direntry->tdir_offset); */ - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(value); + *value = direntry->tdir_offset.toff_short; + /* *value=*(uint16_t*)(&direntry->tdir_offset); */ + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(value); } -static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16_t* value) +static void TIFFReadDirEntryCheckedSshort(TIFF *tif, TIFFDirEntry *direntry, + int16_t *value) { - *value=*(int16_t*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)value); + *value = *(int16_t *)(&direntry->tdir_offset); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)value); } -static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32_t* value) +static void TIFFReadDirEntryCheckedLong(TIFF *tif, TIFFDirEntry *direntry, + uint32_t *value) { - *value=*(uint32_t*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(value); + *value = *(uint32_t *)(&direntry->tdir_offset); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(value); } -static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32_t* value) +static void TIFFReadDirEntryCheckedSlong(TIFF *tif, TIFFDirEntry *direntry, + int32_t *value) { - *value=*(int32_t*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)value); + *value = *(int32_t *)(&direntry->tdir_offset); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)value); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64_t* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedLong8(TIFF *tif, TIFFDirEntry *direntry, uint64_t *value) { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,value); - if (err!=TIFFReadDirEntryErrOk) - return(err); - } - else - *value = direntry->tdir_offset.toff_long8; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(value); - return(TIFFReadDirEntryErrOk); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, value); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + *value = direntry->tdir_offset.toff_long8; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(value); + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64_t* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedSlong8(TIFF *tif, TIFFDirEntry *direntry, int64_t *value) { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,value); - if (err!=TIFFReadDirEntryErrOk) - return(err); - } - else - *value=*(int64_t*)(&direntry->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)value); - return(TIFFReadDirEntryErrOk); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, value); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + *value = *(int64_t *)(&direntry->tdir_offset); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)value); + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedRational(TIFF *tif, TIFFDirEntry *direntry, + double *value) { - UInt64Aligned_t m; - - assert(sizeof(double)==8); - assert(sizeof(uint64_t) == 8); - assert(sizeof(uint32_t) == 4); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,m.i); - if (err!=TIFFReadDirEntryErrOk) - return(err); - } - else - m.l = direntry->tdir_offset.toff_long8; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(m.i,2); - /* Not completely sure what we should do when m.i[1]==0, but some */ - /* sanitizers do not like division by 0.0: */ - /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ - if (m.i[0]==0 || m.i[1]==0) - *value=0.0; - else - *value=(double)m.i[0]/(double)m.i[1]; - return(TIFFReadDirEntryErrOk); + UInt64Aligned_t m; + + assert(sizeof(double) == 8); + assert(sizeof(uint64_t) == 8); + assert(sizeof(uint32_t) == 4); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, m.i); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + m.l = direntry->tdir_offset.toff_long8; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m.i, 2); + /* Not completely sure what we should do when m.i[1]==0, but some */ + /* sanitizers do not like division by 0.0: */ + /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ + if (m.i[0] == 0 || m.i[1] == 0) + *value = 0.0; + else + *value = (double)m.i[0] / (double)m.i[1]; + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedSrational(TIFF *tif, TIFFDirEntry *direntry, + double *value) { - UInt64Aligned_t m; - assert(sizeof(double)==8); - assert(sizeof(uint64_t) == 8); - assert(sizeof(int32_t) == 4); - assert(sizeof(uint32_t) == 4); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,m.i); - if (err!=TIFFReadDirEntryErrOk) - return(err); - } - else - m.l=direntry->tdir_offset.toff_long8; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(m.i,2); - /* Not completely sure what we should do when m.i[1]==0, but some */ - /* sanitizers do not like division by 0.0: */ - /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ - if ((int32_t)m.i[0] == 0 || m.i[1] == 0) - *value=0.0; - else - *value= (double)((int32_t)m.i[0]) / (double)m.i[1]; - return(TIFFReadDirEntryErrOk); + UInt64Aligned_t m; + assert(sizeof(double) == 8); + assert(sizeof(uint64_t) == 8); + assert(sizeof(int32_t) == 4); + assert(sizeof(uint32_t) == 4); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, m.i); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + m.l = direntry->tdir_offset.toff_long8; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m.i, 2); + /* Not completely sure what we should do when m.i[1]==0, but some */ + /* sanitizers do not like division by 0.0: */ + /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */ + if ((int32_t)m.i[0] == 0 || m.i[1] == 0) + *value = 0.0; + else + *value = (double)((int32_t)m.i[0]) / (double)m.i[1]; + return (TIFFReadDirEntryErrOk); } -static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value) +static void TIFFReadDirEntryCheckedFloat(TIFF *tif, TIFFDirEntry *direntry, + float *value) { - union - { - float f; - uint32_t i; - } float_union; - assert(sizeof(float)==4); - assert(sizeof(uint32_t) == 4); - assert(sizeof(float_union)==4); - float_union.i=*(uint32_t*)(&direntry->tdir_offset); - *value=float_union.f; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)value); + union + { + float f; + uint32_t i; + } float_union; + assert(sizeof(float) == 4); + assert(sizeof(uint32_t) == 4); + assert(sizeof(float_union) == 4); + float_union.i = *(uint32_t *)(&direntry->tdir_offset); + *value = float_union.f; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)value); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckedDouble(TIFF *tif, TIFFDirEntry *direntry, double *value) { - assert(sizeof(double)==8); - assert(sizeof(uint64_t) == 8); - assert(sizeof(UInt64Aligned_t)==8); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - enum TIFFReadDirEntryErr err; - uint32_t offset = direntry->tdir_offset.toff_long; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,value); - if (err!=TIFFReadDirEntryErrOk) - return(err); - } - else - { - UInt64Aligned_t uint64_union; - uint64_union.l=direntry->tdir_offset.toff_long8; - *value=uint64_union.d; - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)value); - return(TIFFReadDirEntryErrOk); + assert(sizeof(double) == 8); + assert(sizeof(uint64_t) == 8); + assert(sizeof(UInt64Aligned_t) == 8); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + enum TIFFReadDirEntryErr err; + uint32_t offset = direntry->tdir_offset.toff_long; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, value); + if (err != TIFFReadDirEntryErrOk) + return (err); + } + else + { + UInt64Aligned_t uint64_union; + uint64_union.l = direntry->tdir_offset.toff_long8; + *value = uint64_union.d; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)value); + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSbyte(int8_t value) { - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteShort(uint16_t value) { - if (value>0xFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0xFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSshort(int16_t value) { - if ((value<0)||(value>0xFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < 0) || (value > 0xFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteLong(uint32_t value) { - if (value>0xFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0xFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSlong(int32_t value) { - if ((value<0)||(value>0xFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < 0) || (value > 0xFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteLong8(uint64_t value) { - if (value>0xFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0xFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeByteSlong8(int64_t value) { - if ((value<0)||(value>0xFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < 0) || (value > 0xFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteByte(uint8_t value) { - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0x7F) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteShort(uint16_t value) { - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0x7F) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSshort(int16_t value) { - if ((value<-0x80)||(value>0x7F)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < -0x80) || (value > 0x7F)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteLong(uint32_t value) { - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0x7F) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSlong(int32_t value) { - if ((value<-0x80)||(value>0x7F)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < -0x80) || (value > 0x7F)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteLong8(uint64_t value) { - if (value>0x7F) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0x7F) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSbyteSlong8(int64_t value) { - if ((value<-0x80)||(value>0x7F)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < -0x80) || (value > 0x7F)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSbyte(int8_t value) { - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSshort(int16_t value) { - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortLong(uint32_t value) { - if (value>0xFFFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0xFFFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSlong(int32_t value) { - if ((value<0)||(value>0xFFFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < 0) || (value > 0xFFFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortLong8(uint64_t value) { - if (value>0xFFFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0xFFFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeShortSlong8(int64_t value) { - if ((value<0)||(value>0xFFFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < 0) || (value > 0xFFFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortShort(uint16_t value) { - if (value>0x7FFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0x7FFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortLong(uint32_t value) { - if (value>0x7FFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0x7FFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortSlong(int32_t value) { - if ((value<-0x8000)||(value>0x7FFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < -0x8000) || (value > 0x7FFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortLong8(uint64_t value) { - if (value>0x7FFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0x7FFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeSshortSlong8(int64_t value) { - if ((value<-0x8000)||(value>0x7FFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < -0x8000) || (value > 0x7FFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSbyte(int8_t value) { - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSshort(int16_t value) { - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32_t value) +static enum TIFFReadDirEntryErr +TIFFReadDirEntryCheckRangeLongSlong(int32_t value) { - if (value<0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64_t value) { - if (value > UINT32_MAX) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > UINT32_MAX) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64_t value) { - if ((value < 0) || (value > (int64_t) UINT32_MAX)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < 0) || (value > (int64_t)UINT32_MAX)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32_t value) { - if (value > 0x7FFFFFFFUL) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0x7FFFFFFFUL) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } /* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64_t value) { - if (value > 0x7FFFFFFF) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > 0x7FFFFFFF) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } /* Check that the 8-byte signed value can fit in a 4-byte signed range */ static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64_t value) { - if ((value < 0-((int64_t) 0x7FFFFFFF + 1)) || (value > 0x7FFFFFFF)) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if ((value < 0 - ((int64_t)0x7FFFFFFF + 1)) || (value > 0x7FFFFFFF)) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8_t value) { - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16_t value) { - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32_t value) { - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64_t value) { - if (value < 0) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value < 0) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64_t value) { - if (value > INT64_MAX) - return(TIFFReadDirEntryErrRange); - else - return(TIFFReadDirEntryErrOk); + if (value > INT64_MAX) + return (TIFFReadDirEntryErrRange); + else + return (TIFFReadDirEntryErrOk); } -static enum TIFFReadDirEntryErr -TIFFReadDirEntryData(TIFF* tif, uint64_t offset, tmsize_t size, void* dest) +static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF *tif, uint64_t offset, + tmsize_t size, void *dest) { - assert(size>0); - if (!isMapped(tif)) { - if (!SeekOK(tif,offset)) - return(TIFFReadDirEntryErrIo); - if (!ReadOK(tif,dest,size)) - return(TIFFReadDirEntryErrIo); - } else { - size_t ma,mb; - ma=(size_t)offset; - if((uint64_t)ma != offset || - ma > (~(size_t)0) - (size_t)size ) - { - return TIFFReadDirEntryErrIo; - } - mb=ma+size; - if (mb > (uint64_t)tif->tif_size) - return(TIFFReadDirEntryErrIo); - _TIFFmemcpy(dest,tif->tif_base+ma,size); - } - return(TIFFReadDirEntryErrOk); + assert(size > 0); + if (!isMapped(tif)) + { + if (!SeekOK(tif, offset)) + return (TIFFReadDirEntryErrIo); + if (!ReadOK(tif, dest, size)) + return (TIFFReadDirEntryErrIo); + } + else + { + size_t ma, mb; + ma = (size_t)offset; + if ((uint64_t)ma != offset || ma > (~(size_t)0) - (size_t)size) + { + return TIFFReadDirEntryErrIo; + } + mb = ma + size; + if (mb > (uint64_t)tif->tif_size) + return (TIFFReadDirEntryErrIo); + _TIFFmemcpy(dest, tif->tif_base + ma, size); + } + return (TIFFReadDirEntryErrOk); } -static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover) +static void TIFFReadDirEntryOutputErr(TIFF *tif, enum TIFFReadDirEntryErr err, + const char *module, const char *tagname, + int recover) { - if (!recover) { - switch (err) { - case TIFFReadDirEntryErrCount: - TIFFErrorExtR(tif, module, - "Incorrect count for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrType: - TIFFErrorExtR(tif, module, - "Incompatible type for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrIo: - TIFFErrorExtR(tif, module, - "IO error during reading of \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrRange: - TIFFErrorExtR(tif, module, - "Incorrect value for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrPsdif: - TIFFErrorExtR(tif, module, - "Cannot handle different values per sample for \"%s\"", - tagname); - break; - case TIFFReadDirEntryErrSizesan: - TIFFErrorExtR(tif, module, - "Sanity check on size of \"%s\" value failed", - tagname); - break; - case TIFFReadDirEntryErrAlloc: - TIFFErrorExtR(tif, module, - "Out of memory reading of \"%s\"", - tagname); - break; - default: - assert(0); /* we should never get here */ - break; - } - } else { - switch (err) { - case TIFFReadDirEntryErrCount: - TIFFWarningExtR(tif, module, - "Incorrect count for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrType: - TIFFWarningExtR(tif, module, - "Incompatible type for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrIo: - TIFFWarningExtR(tif, module, - "IO error during reading of \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrRange: - TIFFWarningExtR(tif, module, - "Incorrect value for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrPsdif: - TIFFWarningExtR(tif, module, - "Cannot handle different values per sample for \"%s\"; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrSizesan: - TIFFWarningExtR(tif, module, - "Sanity check on size of \"%s\" value failed; tag ignored", - tagname); - break; - case TIFFReadDirEntryErrAlloc: - TIFFWarningExtR(tif, module, - "Out of memory reading of \"%s\"; tag ignored", - tagname); - break; - default: - assert(0); /* we should never get here */ - break; - } - } + if (!recover) + { + switch (err) + { + case TIFFReadDirEntryErrCount: + TIFFErrorExtR(tif, module, "Incorrect count for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrType: + TIFFErrorExtR(tif, module, "Incompatible type for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrIo: + TIFFErrorExtR(tif, module, "IO error during reading of \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrRange: + TIFFErrorExtR(tif, module, "Incorrect value for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrPsdif: + TIFFErrorExtR( + tif, module, + "Cannot handle different values per sample for \"%s\"", + tagname); + break; + case TIFFReadDirEntryErrSizesan: + TIFFErrorExtR(tif, module, + "Sanity check on size of \"%s\" value failed", + tagname); + break; + case TIFFReadDirEntryErrAlloc: + TIFFErrorExtR(tif, module, "Out of memory reading of \"%s\"", + tagname); + break; + default: + assert(0); /* we should never get here */ + break; + } + } + else + { + switch (err) + { + case TIFFReadDirEntryErrCount: + TIFFWarningExtR(tif, module, + "Incorrect count for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrType: + TIFFWarningExtR(tif, module, + "Incompatible type for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrIo: + TIFFWarningExtR( + tif, module, + "IO error during reading of \"%s\"; tag ignored", tagname); + break; + case TIFFReadDirEntryErrRange: + TIFFWarningExtR(tif, module, + "Incorrect value for \"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrPsdif: + TIFFWarningExtR(tif, module, + "Cannot handle different values per sample for " + "\"%s\"; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrSizesan: + TIFFWarningExtR( + tif, module, + "Sanity check on size of \"%s\" value failed; tag ignored", + tagname); + break; + case TIFFReadDirEntryErrAlloc: + TIFFWarningExtR(tif, module, + "Out of memory reading of \"%s\"; tag ignored", + tagname); + break; + default: + assert(0); /* we should never get here */ + break; + } + } } /* @@ -3803,1206 +3980,1304 @@ static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, c * type. 0 is returned if photometric type isn't supported or no default value * is defined by the specification. */ -static int _TIFFGetMaxColorChannels(uint16_t photometric ) +static int _TIFFGetMaxColorChannels(uint16_t photometric) { - switch (photometric) { - case PHOTOMETRIC_PALETTE: - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: + switch (photometric) + { + case PHOTOMETRIC_PALETTE: + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: return 1; - case PHOTOMETRIC_YCBCR: - case PHOTOMETRIC_RGB: - case PHOTOMETRIC_CIELAB: - case PHOTOMETRIC_LOGLUV: - case PHOTOMETRIC_ITULAB: - case PHOTOMETRIC_ICCLAB: + case PHOTOMETRIC_YCBCR: + case PHOTOMETRIC_RGB: + case PHOTOMETRIC_CIELAB: + case PHOTOMETRIC_LOGLUV: + case PHOTOMETRIC_ITULAB: + case PHOTOMETRIC_ICCLAB: return 3; - case PHOTOMETRIC_SEPARATED: - case PHOTOMETRIC_MASK: + case PHOTOMETRIC_SEPARATED: + case PHOTOMETRIC_MASK: return 4; - case PHOTOMETRIC_LOGL: - case PHOTOMETRIC_CFA: - default: + case PHOTOMETRIC_LOGL: + case PHOTOMETRIC_CFA: + default: return 0; } } -static int ByteCountLooksBad(TIFF* tif) +static int ByteCountLooksBad(TIFF *tif) { /* - * Assume we have wrong StripByteCount value (in case - * of single strip) in following cases: - * - it is equal to zero along with StripOffset; - * - it is larger than file itself (in case of uncompressed - * image); - * - it is smaller than the size of the bytes per row - * multiplied on the number of rows. The last case should - * not be checked in the case of writing new image, - * because we may do not know the exact strip size - * until the whole image will be written and directory - * dumped out. - */ + * Assume we have wrong StripByteCount value (in case + * of single strip) in following cases: + * - it is equal to zero along with StripOffset; + * - it is larger than file itself (in case of uncompressed + * image); + * - it is smaller than the size of the bytes per row + * multiplied on the number of rows. The last case should + * not be checked in the case of writing new image, + * because we may do not know the exact strip size + * until the whole image will be written and directory + * dumped out. + */ uint64_t bytecount = TIFFGetStrileByteCount(tif, 0); uint64_t offset = TIFFGetStrileOffset(tif, 0); uint64_t filesize; - if( offset == 0 ) + if (offset == 0) return 0; if (bytecount == 0) return 1; - if ( tif->tif_dir.td_compression != COMPRESSION_NONE ) + if (tif->tif_dir.td_compression != COMPRESSION_NONE) return 0; filesize = TIFFGetFileSize(tif); - if( offset <= filesize && bytecount > filesize - offset ) + if (offset <= filesize && bytecount > filesize - offset) return 1; - if( tif->tif_mode == O_RDONLY ) + if (tif->tif_mode == O_RDONLY) { uint64_t scanlinesize = TIFFScanlineSize64(tif); - if( tif->tif_dir.td_imagelength > 0 && - scanlinesize > UINT64_MAX / tif->tif_dir.td_imagelength ) + if (tif->tif_dir.td_imagelength > 0 && + scanlinesize > UINT64_MAX / tif->tif_dir.td_imagelength) { return 1; } - if( bytecount < scanlinesize * tif->tif_dir.td_imagelength) + if (bytecount < scanlinesize * tif->tif_dir.td_imagelength) return 1; } return 0; } - /* * Read the next TIFF directory from a file and convert it to the internal * format. We read directories sequentially. */ -int -TIFFReadDirectory(TIFF* tif) +int TIFFReadDirectory(TIFF *tif) { - static const char module[] = "TIFFReadDirectory"; - TIFFDirEntry* dir; - uint16_t dircount; - TIFFDirEntry* dp; - uint16_t di; - const TIFFField* fip; - uint32_t fii=FAILED_FII; - toff_t nextdiroff; + static const char module[] = "TIFFReadDirectory"; + TIFFDirEntry *dir; + uint16_t dircount; + TIFFDirEntry *dp; + uint16_t di; + const TIFFField *fip; + uint32_t fii = FAILED_FII; + toff_t nextdiroff; int bitspersample_read = FALSE; - int color_channels; - - if (tif->tif_nextdiroff == 0) { - /* In this special case, tif_diroff needs also to be set to 0. */ - tif->tif_diroff = tif->tif_nextdiroff; - return 0; /* last offset, thus no checking necessary */ - } - - nextdiroff = tif->tif_nextdiroff; - /* tif_curdir++ and tif_nextdiroff should only be updated after SUCCESSFUL reading of the directory. Otherwise, invalid IFD offsets could corrupt the IFD list. */ - if (!_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir + 1, nextdiroff)) { - TIFFWarningExtR(tif, module, - "Didn't read next directory due to IFD looping at offset 0x%"PRIx64" (%"PRIu64") to offset 0x%"PRIx64" (%"PRIu64")", tif->tif_diroff, tif->tif_diroff, nextdiroff, nextdiroff); - return 0; /* bad offset (IFD looping) */ - } - dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff); - if (!dircount) - { - TIFFErrorExtR(tif,module, - "Failed to read directory at offset %" PRIu64, nextdiroff); - return 0; - } - /* Set global values after a valid directory has been fetched. - * tif_diroff is already set to nextdiroff in TIFFFetchDirectory() in the beginning. */ - tif->tif_curdir++; - (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ - - TIFFReadDirectoryCheckOrder(tif,dir,dircount); + int color_channels; - /* - * Mark duplicates of any tag to be ignored (bugzilla 1994) - * to avoid certain pathological problems. - */ - { - TIFFDirEntry* ma; - uint16_t mb; - for (ma=dir, mb=0; mb<dircount; ma++, mb++) - { - TIFFDirEntry* na; - uint16_t nb; - for (na=ma+1, nb=mb+1; nb<dircount; na++, nb++) - { - if (ma->tdir_tag == na->tdir_tag) { - na->tdir_ignore = TRUE; - } - } - } - } - - tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ - tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */ - tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS; - - /* free any old stuff and reinit */ - TIFFFreeDirectory(tif); - TIFFDefaultDirectory(tif); - /* - * Electronic Arts writes gray-scale TIFF files - * without a PlanarConfiguration directory entry. - * Thus we setup a default value here, even though - * the TIFF spec says there is no default value. - * After PlanarConfiguration is preset in TIFFDefaultDirectory() - * the following setting is not needed, but does not harm either. - */ - TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG); - /* - * Setup default value and then make a pass over - * the fields to check type and tag information, - * and to extract info required to size data - * structures. A second pass is made afterwards - * to read in everything not taken in the first pass. - * But we must process the Compression tag first - * in order to merge in codec-private tag definitions (otherwise - * we may get complaints about unknown tags). However, the - * Compression tag may be dependent on the SamplesPerPixel - * tag value because older TIFF specs permitted Compression - * to be written as a SamplesPerPixel-count tag entry. - * Thus if we don't first figure out the correct SamplesPerPixel - * tag value then we may end up ignoring the Compression tag - * value because it has an incorrect count value (if the - * true value of SamplesPerPixel is not 1). - */ - dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL); - if (dp) - { - if (!TIFFFetchNormalTag(tif,dp,0)) - goto bad; - dp->tdir_ignore = TRUE; - } - dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION); - if (dp) - { - /* - * The 5.0 spec says the Compression tag has one value, while - * earlier specs say it has one value per sample. Because of - * this, we accept the tag if one value is supplied with either - * count. - */ - uint16_t value; - enum TIFFReadDirEntryErr err; - err=TIFFReadDirEntryShort(tif,dp,&value); - if (err==TIFFReadDirEntryErrCount) - err=TIFFReadDirEntryPersampleShort(tif,dp,&value); - if (err!=TIFFReadDirEntryErrOk) - { - TIFFReadDirEntryOutputErr(tif,err,module,"Compression",0); - goto bad; - } - if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value)) - goto bad; - dp->tdir_ignore = TRUE; - } - else - { - if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE)) - goto bad; - } - /* - * First real pass over the directory. - */ - for (di=0, dp=dir; di<dircount; di++, dp++) - { - if (!dp->tdir_ignore) - { - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - if (fii == FAILED_FII) - { - TIFFWarningExtR(tif, module, - "Unknown field with tag %"PRIu16" (0x%"PRIx16") encountered", - dp->tdir_tag,dp->tdir_tag); - /* the following knowingly leaks the - anonymous field structure */ - if (!_TIFFMergeFields(tif, - _TIFFCreateAnonField(tif, - dp->tdir_tag, - (TIFFDataType) dp->tdir_type), - 1)) { - TIFFWarningExtR(tif, - module, - "Registering anonymous field with tag %"PRIu16" (0x%"PRIx16") failed", - dp->tdir_tag, - dp->tdir_tag); - dp->tdir_ignore = TRUE; - } else { - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - assert(fii != FAILED_FII); - } - } - } - if (!dp->tdir_ignore) - { - fip=tif->tif_fields[fii]; - if (fip->field_bit==FIELD_IGNORE) - dp->tdir_ignore = TRUE; - else - { - switch (dp->tdir_tag) - { - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEOFFSETS: - case TIFFTAG_TILEBYTECOUNTS: - TIFFSetFieldBit(tif,fip->field_bit); - break; - case TIFFTAG_IMAGEWIDTH: - case TIFFTAG_IMAGELENGTH: - case TIFFTAG_IMAGEDEPTH: - case TIFFTAG_TILELENGTH: - case TIFFTAG_TILEWIDTH: - case TIFFTAG_TILEDEPTH: - case TIFFTAG_PLANARCONFIG: - case TIFFTAG_ROWSPERSTRIP: - case TIFFTAG_EXTRASAMPLES: - if (!TIFFFetchNormalTag(tif,dp,0)) - goto bad; - dp->tdir_ignore = TRUE; - break; - default: - if( !_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag) ) - dp->tdir_ignore = TRUE; - break; - } - } - } - } - /* - * XXX: OJPEG hack. - * If a) compression is OJPEG, b) planarconfig tag says it's separate, - * c) strip offsets/bytecounts tag are both present and - * d) both contain exactly one value, then we consistently find - * that the buggy implementation of the buggy compression scheme - * matches contig planarconfig best. So we 'fix-up' the tag here - */ - if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&& - (tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE)) - { - if (!_TIFFFillStriles(tif)) - goto bad; - dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS); - if ((dp!=0)&&(dp->tdir_count==1)) - { - dp=TIFFReadDirectoryFindEntry(tif,dir,dircount, - TIFFTAG_STRIPBYTECOUNTS); - if ((dp!=0)&&(dp->tdir_count==1)) - { - tif->tif_dir.td_planarconfig=PLANARCONFIG_CONTIG; - TIFFWarningExtR(tif,module, - "Planarconfig tag value assumed incorrect, " - "assuming data is contig instead of chunky"); - } - } - } - /* - * Allocate directory structure and setup defaults. - */ - if (!TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) - { - MissingRequired(tif,"ImageLength"); - goto bad; - } - - /* - * Second pass: extract other information. - */ - for (di=0, dp=dir; di<dircount; di++, dp++) - { - if (!dp->tdir_ignore) { - switch (dp->tdir_tag) - { - case TIFFTAG_MINSAMPLEVALUE: - case TIFFTAG_MAXSAMPLEVALUE: - case TIFFTAG_BITSPERSAMPLE: - case TIFFTAG_DATATYPE: - case TIFFTAG_SAMPLEFORMAT: - /* - * The MinSampleValue, MaxSampleValue, BitsPerSample - * DataType and SampleFormat tags are supposed to be - * written as one value/sample, but some vendors - * incorrectly write one value only -- so we accept - * that as well (yuck). Other vendors write correct - * value for NumberOfSamples, but incorrect one for - * BitsPerSample and friends, and we will read this - * too. - */ - { - uint16_t value; - enum TIFFReadDirEntryErr err; - err=TIFFReadDirEntryShort(tif,dp,&value); - if (err==TIFFReadDirEntryErrCount) - err=TIFFReadDirEntryPersampleShort(tif,dp,&value); - if (err!=TIFFReadDirEntryErrOk) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); - goto bad; - } - if (!TIFFSetField(tif,dp->tdir_tag,value)) - goto bad; - if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE ) - bitspersample_read = TRUE; - } - break; - case TIFFTAG_SMINSAMPLEVALUE: - case TIFFTAG_SMAXSAMPLEVALUE: - { - - double *data = NULL; - enum TIFFReadDirEntryErr err; - uint32_t saved_flags; - int m; - if (dp->tdir_count != (uint64_t)tif->tif_dir.td_samplesperpixel) - err = TIFFReadDirEntryErrCount; - else - err = TIFFReadDirEntryDoubleArray(tif, dp, &data); - if (err!=TIFFReadDirEntryErrOk) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); - goto bad; - } - saved_flags = tif->tif_flags; - tif->tif_flags |= TIFF_PERSAMPLE; - m = TIFFSetField(tif,dp->tdir_tag,data); - tif->tif_flags = saved_flags; - _TIFFfreeExt(tif, data); - if (!m) - goto bad; - } - break; - case TIFFTAG_STRIPOFFSETS: - case TIFFTAG_TILEOFFSETS: - switch( dp->tdir_type ) - { - case TIFF_SHORT: - case TIFF_LONG: - case TIFF_LONG8: - break; - default: - /* Warn except if directory typically created with TIFFDeferStrileArrayWriting() */ - if( !(tif->tif_mode == O_RDWR && - dp->tdir_count == 0 && - dp->tdir_type == 0 && - dp->tdir_offset.toff_long8 == 0) ) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFWarningExtR(tif,module, - "Invalid data type for tag %s", - fip ? fip->field_name : "unknown tagname"); - } - break; - } - _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry), - dp, sizeof(TIFFDirEntry) ); - break; - case TIFFTAG_STRIPBYTECOUNTS: - case TIFFTAG_TILEBYTECOUNTS: - switch( dp->tdir_type ) - { - case TIFF_SHORT: - case TIFF_LONG: - case TIFF_LONG8: - break; - default: - /* Warn except if directory typically created with TIFFDeferStrileArrayWriting() */ - if( !(tif->tif_mode == O_RDWR && - dp->tdir_count == 0 && - dp->tdir_type == 0 && - dp->tdir_offset.toff_long8 == 0) ) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFWarningExtR(tif,module, - "Invalid data type for tag %s", - fip ? fip->field_name : "unknown tagname"); - } - break; - } - _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry), - dp, sizeof(TIFFDirEntry) ); - break; - case TIFFTAG_COLORMAP: - case TIFFTAG_TRANSFERFUNCTION: - { - enum TIFFReadDirEntryErr err; - uint32_t countpersample; - uint32_t countrequired; - uint32_t incrementpersample; - uint16_t* value=NULL; - /* It would be dangerous to instantiate those tag values */ - /* since if td_bitspersample has not yet been read (due to */ - /* unordered tags), it could be read afterwards with a */ - /* values greater than the default one (1), which may cause */ - /* crashes in user code */ - if( !bitspersample_read ) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFWarningExtR(tif,module, - "Ignoring %s since BitsPerSample tag not found", - fip ? fip->field_name : "unknown tagname"); - continue; - } - /* ColorMap or TransferFunction for high bit */ - /* depths do not make much sense and could be */ - /* used as a denial of service vector */ - if (tif->tif_dir.td_bitspersample > 24) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFWarningExtR(tif,module, - "Ignoring %s because BitsPerSample=%"PRIu16">24", - fip ? fip->field_name : "unknown tagname", - tif->tif_dir.td_bitspersample); - continue; - } - countpersample=(1U<<tif->tif_dir.td_bitspersample); - if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64_t)countpersample)) - { - countrequired=countpersample; - incrementpersample=0; - } - else - { - countrequired=3*countpersample; - incrementpersample=countpersample; - } - if (dp->tdir_count!=(uint64_t)countrequired) - err=TIFFReadDirEntryErrCount; - else - err=TIFFReadDirEntryShortArray(tif,dp,&value); - if (err!=TIFFReadDirEntryErrOk) - { - fip = TIFFFieldWithTag(tif,dp->tdir_tag); - TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1); - } - else - { - TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample); - _TIFFfreeExt(tif, value); - } - } - break; -/* BEGIN REV 4.0 COMPATIBILITY */ - case TIFFTAG_OSUBFILETYPE: - { - uint16_t valueo; - uint32_t value; - if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk) - { - switch (valueo) - { - case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break; - case OFILETYPE_PAGE: value=FILETYPE_PAGE; break; - default: value=0; break; - } - if (value!=0) - TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value); - } - } - break; -/* END REV 4.0 COMPATIBILITY */ - default: - (void) TIFFFetchNormalTag(tif, dp, TRUE); - break; - } - } /* -- if (!dp->tdir_ignore) */ - } /* -- for-loop -- */ - - /* - * OJPEG hack: - * - If a) compression is OJPEG, and b) photometric tag is missing, - * then we consistently find that photometric should be YCbCr - * - If a) compression is OJPEG, and b) photometric tag says it's RGB, - * then we consistently find that the buggy implementation of the - * buggy compression scheme matches photometric YCbCr instead. - * - If a) compression is OJPEG, and b) bitspersample tag is missing, - * then we consistently find bitspersample should be 8. - * - If a) compression is OJPEG, b) samplesperpixel tag is missing, - * and c) photometric is RGB or YCbCr, then we consistently find - * samplesperpixel should be 3 - * - If a) compression is OJPEG, b) samplesperpixel tag is missing, - * and c) photometric is MINISWHITE or MINISBLACK, then we consistently - * find samplesperpixel should be 3 - */ - if (tif->tif_dir.td_compression==COMPRESSION_OJPEG) - { - if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) - { - TIFFWarningExtR(tif, module, - "Photometric tag is missing, assuming data is YCbCr"); - if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR)) - goto bad; - } - else if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB) - { - tif->tif_dir.td_photometric=PHOTOMETRIC_YCBCR; - TIFFWarningExtR(tif, module, - "Photometric tag value assumed incorrect, " - "assuming data is YCbCr instead of RGB"); - } - if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) - { - TIFFWarningExtR(tif,module, - "BitsPerSample tag is missing, assuming 8 bits per sample"); - if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8)) - goto bad; - } - if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) - { - if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB) - { - TIFFWarningExtR(tif,module, - "SamplesPerPixel tag is missing, " - "assuming correct SamplesPerPixel value is 3"); - if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3)) - goto bad; - } - if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR) - { - TIFFWarningExtR(tif,module, - "SamplesPerPixel tag is missing, " - "applying correct SamplesPerPixel value of 3"); - if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3)) - goto bad; - } - else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE) - || (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK)) - { - /* - * SamplesPerPixel tag is missing, but is not required - * by spec. Assume correct SamplesPerPixel value of 1. - */ - if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1)) - goto bad; - } - } - } - - /* - * Setup appropriate structures (by strip or by tile) - * We do that only after the above OJPEG hack which alters SamplesPerPixel - * and thus influences the number of strips in the separate planarconfig. - */ - if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { - tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif); - tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth; - tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip; - tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth; - tif->tif_flags &= ~TIFF_ISTILED; - } else { - tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif); - tif->tif_flags |= TIFF_ISTILED; - } - if (!tif->tif_dir.td_nstrips) { - TIFFErrorExtR(tif, module, - "Cannot handle zero number of %s", - isTiled(tif) ? "tiles" : "strips"); - goto bad; - } - tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips; - if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE) - tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel; - if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) { -#ifdef OJPEG_SUPPORT - if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) && - (isTiled(tif)==0) && - (tif->tif_dir.td_nstrips==1)) { - /* - * XXX: OJPEG hack. - * If a) compression is OJPEG, b) it's not a tiled TIFF, - * and c) the number of strips is 1, - * then we tolerate the absence of stripoffsets tag, - * because, presumably, all required data is in the - * JpegInterchangeFormat stream. - */ - TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); - } else -#endif + if (tif->tif_nextdiroff == 0) + { + /* In this special case, tif_diroff needs also to be set to 0. */ + tif->tif_diroff = tif->tif_nextdiroff; + return 0; /* last offset, thus no checking necessary */ + } + + nextdiroff = tif->tif_nextdiroff; + /* tif_curdir++ and tif_nextdiroff should only be updated after SUCCESSFUL + * reading of the directory. Otherwise, invalid IFD offsets could corrupt + * the IFD list. */ + if (!_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir + 1, nextdiroff)) + { + TIFFWarningExtR( + tif, module, + "Didn't read next directory due to IFD looping at offset 0x%" PRIx64 + " (%" PRIu64 ") to offset 0x%" PRIx64 " (%" PRIu64 ")", + tif->tif_diroff, tif->tif_diroff, nextdiroff, nextdiroff); + return 0; /* bad offset (IFD looping) */ + } + dircount = TIFFFetchDirectory(tif, nextdiroff, &dir, &tif->tif_nextdiroff); + if (!dircount) + { + TIFFErrorExtR(tif, module, + "Failed to read directory at offset %" PRIu64, + nextdiroff); + return 0; + } + /* Set global values after a valid directory has been fetched. + * tif_diroff is already set to nextdiroff in TIFFFetchDirectory() in the + * beginning. */ + tif->tif_curdir++; + (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ + + TIFFReadDirectoryCheckOrder(tif, dir, dircount); + + /* + * Mark duplicates of any tag to be ignored (bugzilla 1994) + * to avoid certain pathological problems. + */ + { + TIFFDirEntry *ma; + uint16_t mb; + for (ma = dir, mb = 0; mb < dircount; ma++, mb++) { - MissingRequired(tif, - isTiled(tif) ? "TileOffsets" : "StripOffsets"); - goto bad; - } - } + TIFFDirEntry *na; + uint16_t nb; + for (na = ma + 1, nb = mb + 1; nb < dircount; na++, nb++) + { + if (ma->tdir_tag == na->tdir_tag) + { + na->tdir_ignore = TRUE; + } + } + } + } + + tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */ + tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */ + tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS; - if( tif->tif_mode == O_RDWR && - tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && - tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 ) + /* free any old stuff and reinit */ + TIFFFreeDirectory(tif); + TIFFDefaultDirectory(tif); + /* + * Electronic Arts writes gray-scale TIFF files + * without a PlanarConfiguration directory entry. + * Thus we setup a default value here, even though + * the TIFF spec says there is no default value. + * After PlanarConfiguration is preset in TIFFDefaultDirectory() + * the following setting is not needed, but does not harm either. + */ + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + /* + * Setup default value and then make a pass over + * the fields to check type and tag information, + * and to extract info required to size data + * structures. A second pass is made afterwards + * to read in everything not taken in the first pass. + * But we must process the Compression tag first + * in order to merge in codec-private tag definitions (otherwise + * we may get complaints about unknown tags). However, the + * Compression tag may be dependent on the SamplesPerPixel + * tag value because older TIFF specs permitted Compression + * to be written as a SamplesPerPixel-count tag entry. + * Thus if we don't first figure out the correct SamplesPerPixel + * tag value then we may end up ignoring the Compression tag + * value because it has an incorrect count value (if the + * true value of SamplesPerPixel is not 1). + */ + dp = + TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_SAMPLESPERPIXEL); + if (dp) + { + if (!TIFFFetchNormalTag(tif, dp, 0)) + goto bad; + dp->tdir_ignore = TRUE; + } + dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, TIFFTAG_COMPRESSION); + if (dp) + { + /* + * The 5.0 spec says the Compression tag has one value, while + * earlier specs say it has one value per sample. Because of + * this, we accept the tag if one value is supplied with either + * count. + */ + uint16_t value; + enum TIFFReadDirEntryErr err; + err = TIFFReadDirEntryShort(tif, dp, &value); + if (err == TIFFReadDirEntryErrCount) + err = TIFFReadDirEntryPersampleShort(tif, dp, &value); + if (err != TIFFReadDirEntryErrOk) { - /* Directory typically created with TIFFDeferStrileArrayWriting() */ - TIFFSetupStrips(tif); + TIFFReadDirEntryOutputErr(tif, err, module, "Compression", 0); + goto bad; } - else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) ) + if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, value)) + goto bad; + dp->tdir_ignore = TRUE; + } + else + { + if (!TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE)) + goto bad; + } + /* + * First real pass over the directory. + */ + for (di = 0, dp = dir; di < dircount; di++, dp++) + { + if (!dp->tdir_ignore) { - if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 ) + TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); + if (fii == FAILED_FII) { - if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry), - tif->tif_dir.td_nstrips, - &tif->tif_dir.td_stripoffset_p)) + TIFFWarningExtR(tif, module, + "Unknown field with tag %" PRIu16 " (0x%" PRIx16 + ") encountered", + dp->tdir_tag, dp->tdir_tag); + /* the following knowingly leaks the + anonymous field structure */ + if (!_TIFFMergeFields( + tif, + _TIFFCreateAnonField(tif, dp->tdir_tag, + (TIFFDataType)dp->tdir_type), + 1)) { - goto bad; + TIFFWarningExtR( + tif, module, + "Registering anonymous field with tag %" PRIu16 + " (0x%" PRIx16 ") failed", + dp->tdir_tag, dp->tdir_tag); + dp->tdir_ignore = TRUE; + } + else + { + TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); + assert(fii != FAILED_FII); } } - if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 ) + } + if (!dp->tdir_ignore) + { + fip = tif->tif_fields[fii]; + if (fip->field_bit == FIELD_IGNORE) + dp->tdir_ignore = TRUE; + else { - if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry), - tif->tif_dir.td_nstrips, - &tif->tif_dir.td_stripbytecount_p)) + switch (dp->tdir_tag) { - goto bad; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEOFFSETS: + case TIFFTAG_TILEBYTECOUNTS: + TIFFSetFieldBit(tif, fip->field_bit); + break; + case TIFFTAG_IMAGEWIDTH: + case TIFFTAG_IMAGELENGTH: + case TIFFTAG_IMAGEDEPTH: + case TIFFTAG_TILELENGTH: + case TIFFTAG_TILEWIDTH: + case TIFFTAG_TILEDEPTH: + case TIFFTAG_PLANARCONFIG: + case TIFFTAG_ROWSPERSTRIP: + case TIFFTAG_EXTRASAMPLES: + if (!TIFFFetchNormalTag(tif, dp, 0)) + goto bad; + dp->tdir_ignore = TRUE; + break; + default: + if (!_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag)) + dp->tdir_ignore = TRUE; + break; } } } + } + /* + * XXX: OJPEG hack. + * If a) compression is OJPEG, b) planarconfig tag says it's separate, + * c) strip offsets/bytecounts tag are both present and + * d) both contain exactly one value, then we consistently find + * that the buggy implementation of the buggy compression scheme + * matches contig planarconfig best. So we 'fix-up' the tag here + */ + if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) && + (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)) + { + if (!_TIFFFillStriles(tif)) + goto bad; + dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, + TIFFTAG_STRIPOFFSETS); + if ((dp != 0) && (dp->tdir_count == 1)) + { + dp = TIFFReadDirectoryFindEntry(tif, dir, dircount, + TIFFTAG_STRIPBYTECOUNTS); + if ((dp != 0) && (dp->tdir_count == 1)) + { + tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG; + TIFFWarningExtR(tif, module, + "Planarconfig tag value assumed incorrect, " + "assuming data is contig instead of chunky"); + } + } + } + /* + * Allocate directory structure and setup defaults. + */ + if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) + { + MissingRequired(tif, "ImageLength"); + goto bad; + } - /* - * Make sure all non-color channels are extrasamples. - * If it's not the case, define them as such. - */ - color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric); - if (color_channels && tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > color_channels) { - uint16_t old_extrasamples; - uint16_t *new_sampleinfo; - - TIFFWarningExtR(tif,module, "Sum of Photometric type-related " - "color channels and ExtraSamples doesn't match SamplesPerPixel. " - "Defining non-color channels as ExtraSamples."); - - old_extrasamples = tif->tif_dir.td_extrasamples; - tif->tif_dir.td_extrasamples = (uint16_t) (tif->tif_dir.td_samplesperpixel - color_channels); + /* + * Second pass: extract other information. + */ + for (di = 0, dp = dir; di < dircount; di++, dp++) + { + if (!dp->tdir_ignore) + { + switch (dp->tdir_tag) + { + case TIFFTAG_MINSAMPLEVALUE: + case TIFFTAG_MAXSAMPLEVALUE: + case TIFFTAG_BITSPERSAMPLE: + case TIFFTAG_DATATYPE: + case TIFFTAG_SAMPLEFORMAT: + /* + * The MinSampleValue, MaxSampleValue, BitsPerSample + * DataType and SampleFormat tags are supposed to be + * written as one value/sample, but some vendors + * incorrectly write one value only -- so we accept + * that as well (yuck). Other vendors write correct + * value for NumberOfSamples, but incorrect one for + * BitsPerSample and friends, and we will read this + * too. + */ + { + uint16_t value; + enum TIFFReadDirEntryErr err; + err = TIFFReadDirEntryShort(tif, dp, &value); + if (err == TIFFReadDirEntryErrCount) + err = + TIFFReadDirEntryPersampleShort(tif, dp, &value); + if (err != TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFReadDirEntryOutputErr( + tif, err, module, + fip ? fip->field_name : "unknown tagname", 0); + goto bad; + } + if (!TIFFSetField(tif, dp->tdir_tag, value)) + goto bad; + if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE) + bitspersample_read = TRUE; + } + break; + case TIFFTAG_SMINSAMPLEVALUE: + case TIFFTAG_SMAXSAMPLEVALUE: + { - // sampleinfo should contain information relative to these new extra samples - new_sampleinfo = (uint16_t*) _TIFFcallocExt(tif, tif->tif_dir.td_extrasamples, sizeof(uint16_t)); - if (!new_sampleinfo) { - TIFFErrorExtR(tif, module, "Failed to allocate memory for " - "temporary new sampleinfo array " - "(%"PRIu16" 16 bit elements)", - tif->tif_dir.td_extrasamples); - goto bad; + double *data = NULL; + enum TIFFReadDirEntryErr err; + uint32_t saved_flags; + int m; + if (dp->tdir_count != + (uint64_t)tif->tif_dir.td_samplesperpixel) + err = TIFFReadDirEntryErrCount; + else + err = TIFFReadDirEntryDoubleArray(tif, dp, &data); + if (err != TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFReadDirEntryOutputErr( + tif, err, module, + fip ? fip->field_name : "unknown tagname", 0); + goto bad; + } + saved_flags = tif->tif_flags; + tif->tif_flags |= TIFF_PERSAMPLE; + m = TIFFSetField(tif, dp->tdir_tag, data); + tif->tif_flags = saved_flags; + _TIFFfreeExt(tif, data); + if (!m) + goto bad; } + break; + case TIFFTAG_STRIPOFFSETS: + case TIFFTAG_TILEOFFSETS: + switch (dp->tdir_type) + { + case TIFF_SHORT: + case TIFF_LONG: + case TIFF_LONG8: + break; + default: + /* Warn except if directory typically created with + * TIFFDeferStrileArrayWriting() */ + if (!(tif->tif_mode == O_RDWR && + dp->tdir_count == 0 && dp->tdir_type == 0 && + dp->tdir_offset.toff_long8 == 0)) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFWarningExtR( + tif, module, "Invalid data type for tag %s", + fip ? fip->field_name : "unknown tagname"); + } + break; + } + _TIFFmemcpy(&(tif->tif_dir.td_stripoffset_entry), dp, + sizeof(TIFFDirEntry)); + break; + case TIFFTAG_STRIPBYTECOUNTS: + case TIFFTAG_TILEBYTECOUNTS: + switch (dp->tdir_type) + { + case TIFF_SHORT: + case TIFF_LONG: + case TIFF_LONG8: + break; + default: + /* Warn except if directory typically created with + * TIFFDeferStrileArrayWriting() */ + if (!(tif->tif_mode == O_RDWR && + dp->tdir_count == 0 && dp->tdir_type == 0 && + dp->tdir_offset.toff_long8 == 0)) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFWarningExtR( + tif, module, "Invalid data type for tag %s", + fip ? fip->field_name : "unknown tagname"); + } + break; + } + _TIFFmemcpy(&(tif->tif_dir.td_stripbytecount_entry), dp, + sizeof(TIFFDirEntry)); + break; + case TIFFTAG_COLORMAP: + case TIFFTAG_TRANSFERFUNCTION: + { + enum TIFFReadDirEntryErr err; + uint32_t countpersample; + uint32_t countrequired; + uint32_t incrementpersample; + uint16_t *value = NULL; + /* It would be dangerous to instantiate those tag values */ + /* since if td_bitspersample has not yet been read (due to + */ + /* unordered tags), it could be read afterwards with a */ + /* values greater than the default one (1), which may cause + */ + /* crashes in user code */ + if (!bitspersample_read) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFWarningExtR( + tif, module, + "Ignoring %s since BitsPerSample tag not found", + fip ? fip->field_name : "unknown tagname"); + continue; + } + /* ColorMap or TransferFunction for high bit */ + /* depths do not make much sense and could be */ + /* used as a denial of service vector */ + if (tif->tif_dir.td_bitspersample > 24) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFWarningExtR( + tif, module, + "Ignoring %s because BitsPerSample=%" PRIu16 ">24", + fip ? fip->field_name : "unknown tagname", + tif->tif_dir.td_bitspersample); + continue; + } + countpersample = (1U << tif->tif_dir.td_bitspersample); + if ((dp->tdir_tag == TIFFTAG_TRANSFERFUNCTION) && + (dp->tdir_count == (uint64_t)countpersample)) + { + countrequired = countpersample; + incrementpersample = 0; + } + else + { + countrequired = 3 * countpersample; + incrementpersample = countpersample; + } + if (dp->tdir_count != (uint64_t)countrequired) + err = TIFFReadDirEntryErrCount; + else + err = TIFFReadDirEntryShortArray(tif, dp, &value); + if (err != TIFFReadDirEntryErrOk) + { + fip = TIFFFieldWithTag(tif, dp->tdir_tag); + TIFFReadDirEntryOutputErr( + tif, err, module, + fip ? fip->field_name : "unknown tagname", 1); + } + else + { + TIFFSetField(tif, dp->tdir_tag, value, + value + incrementpersample, + value + 2 * incrementpersample); + _TIFFfreeExt(tif, value); + } + } + break; + /* BEGIN REV 4.0 COMPATIBILITY */ + case TIFFTAG_OSUBFILETYPE: + { + uint16_t valueo; + uint32_t value; + if (TIFFReadDirEntryShort(tif, dp, &valueo) == + TIFFReadDirEntryErrOk) + { + switch (valueo) + { + case OFILETYPE_REDUCEDIMAGE: + value = FILETYPE_REDUCEDIMAGE; + break; + case OFILETYPE_PAGE: + value = FILETYPE_PAGE; + break; + default: + value = 0; + break; + } + if (value != 0) + TIFFSetField(tif, TIFFTAG_SUBFILETYPE, value); + } + } + break; + /* END REV 4.0 COMPATIBILITY */ + default: + (void)TIFFFetchNormalTag(tif, dp, TRUE); + break; + } + } /* -- if (!dp->tdir_ignore) */ + } /* -- for-loop -- */ - if (old_extrasamples > 0) - memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16_t)); - _TIFFsetShortArrayExt(tif, &tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples); - _TIFFfreeExt(tif, new_sampleinfo); - } - - /* - * Verify Palette image has a Colormap. - */ - if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE && - !TIFFFieldSet(tif, FIELD_COLORMAP)) { - if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3) - tif->tif_dir.td_photometric = PHOTOMETRIC_RGB; - else if (tif->tif_dir.td_bitspersample>=8) - tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK; - else { - MissingRequired(tif, "Colormap"); - goto bad; - } - } - /* - * OJPEG hack: - * We do no further messing with strip/tile offsets/bytecounts in OJPEG - * TIFFs - */ - if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG) - { - /* - * Attempt to deal with a missing StripByteCounts tag. - */ - if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) { - /* - * Some manufacturers violate the spec by not giving - * the size of the strips. In this case, assume there - * is one uncompressed strip of data. - */ - if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && - tif->tif_dir.td_nstrips > 1) || - (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE && - tif->tif_dir.td_nstrips != (uint32_t)tif->tif_dir.td_samplesperpixel)) { - MissingRequired(tif, "StripByteCounts"); - goto bad; - } - TIFFWarningExtR(tif, module, - "TIFF directory is missing required " - "\"StripByteCounts\" field, calculating from imagelength"); - if (EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; - - } else if (tif->tif_dir.td_nstrips == 1 - && !(tif->tif_flags&TIFF_ISTILED) - && ByteCountLooksBad(tif)) { - /* - * XXX: Plexus (and others) sometimes give a value of - * zero for a tag when they don't know what the - * correct value is! Try and handle the simple case - * of estimating the size of a one strip image. - */ - TIFFWarningExtR(tif, module, - "Bogus \"StripByteCounts\" field, ignoring and calculating from imagelength"); - if(EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; - - } else if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD) - && tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG - && tif->tif_dir.td_nstrips > 2 - && tif->tif_dir.td_compression == COMPRESSION_NONE - && TIFFGetStrileByteCount(tif, 0) != TIFFGetStrileByteCount(tif, 1) - && TIFFGetStrileByteCount(tif, 0) != 0 - && TIFFGetStrileByteCount(tif, 1) != 0 ) { - /* - * XXX: Some vendors fill StripByteCount array with - * absolutely wrong values (it can be equal to - * StripOffset array, for example). Catch this case - * here. - * - * We avoid this check if deferring strile loading - * as it would always force us to load the strip/tile - * information. - */ - TIFFWarningExtR(tif, module, - "Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength"); - if (EstimateStripByteCounts(tif, dir, dircount) < 0) - goto bad; - } - } - if (dir) - { - _TIFFfreeExt(tif, dir); - dir=NULL; - } - if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) - { - if (tif->tif_dir.td_bitspersample>=16) - tif->tif_dir.td_maxsamplevalue=0xFFFF; - else - tif->tif_dir.td_maxsamplevalue = (uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1); - } + /* + * OJPEG hack: + * - If a) compression is OJPEG, and b) photometric tag is missing, + * then we consistently find that photometric should be YCbCr + * - If a) compression is OJPEG, and b) photometric tag says it's RGB, + * then we consistently find that the buggy implementation of the + * buggy compression scheme matches photometric YCbCr instead. + * - If a) compression is OJPEG, and b) bitspersample tag is missing, + * then we consistently find bitspersample should be 8. + * - If a) compression is OJPEG, b) samplesperpixel tag is missing, + * and c) photometric is RGB or YCbCr, then we consistently find + * samplesperpixel should be 3 + * - If a) compression is OJPEG, b) samplesperpixel tag is missing, + * and c) photometric is MINISWHITE or MINISBLACK, then we consistently + * find samplesperpixel should be 3 + */ + if (tif->tif_dir.td_compression == COMPRESSION_OJPEG) + { + if (!TIFFFieldSet(tif, FIELD_PHOTOMETRIC)) + { + TIFFWarningExtR( + tif, module, + "Photometric tag is missing, assuming data is YCbCr"); + if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR)) + goto bad; + } + else if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB) + { + tif->tif_dir.td_photometric = PHOTOMETRIC_YCBCR; + TIFFWarningExtR(tif, module, + "Photometric tag value assumed incorrect, " + "assuming data is YCbCr instead of RGB"); + } + if (!TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) + { + TIFFWarningExtR( + tif, module, + "BitsPerSample tag is missing, assuming 8 bits per sample"); + if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8)) + goto bad; + } + if (!TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) + { + if (tif->tif_dir.td_photometric == PHOTOMETRIC_RGB) + { + TIFFWarningExtR(tif, module, + "SamplesPerPixel tag is missing, " + "assuming correct SamplesPerPixel value is 3"); + if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3)) + goto bad; + } + if (tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) + { + TIFFWarningExtR(tif, module, + "SamplesPerPixel tag is missing, " + "applying correct SamplesPerPixel value of 3"); + if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3)) + goto bad; + } + else if ((tif->tif_dir.td_photometric == PHOTOMETRIC_MINISWHITE) || + (tif->tif_dir.td_photometric == PHOTOMETRIC_MINISBLACK)) + { + /* + * SamplesPerPixel tag is missing, but is not required + * by spec. Assume correct SamplesPerPixel value of 1. + */ + if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1)) + goto bad; + } + } + } -#ifdef STRIPBYTECOUNTSORTED_UNUSED - /* - * XXX: We can optimize checking for the strip bounds using the sorted - * bytecounts array. See also comments for TIFFAppendToStrip() - * function in tif_write.c. - */ - if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1) { - uint32_t strip; - - tif->tif_dir.td_stripbytecountsorted = 1; - for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) { - if (TIFFGetStrileOffset(tif, strip - 1) > - TIFFGetStrileOffset(tif, strip)) { - tif->tif_dir.td_stripbytecountsorted = 0; - break; - } - } - } + /* + * Setup appropriate structures (by strip or by tile) + * We do that only after the above OJPEG hack which alters SamplesPerPixel + * and thus influences the number of strips in the separate planarconfig. + */ + if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) + { + tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif); + tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth; + tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip; + tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth; + tif->tif_flags &= ~TIFF_ISTILED; + } + else + { + tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif); + tif->tif_flags |= TIFF_ISTILED; + } + if (!tif->tif_dir.td_nstrips) + { + TIFFErrorExtR(tif, module, "Cannot handle zero number of %s", + isTiled(tif) ? "tiles" : "strips"); + goto bad; + } + tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips; + if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE) + tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel; + if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) + { +#ifdef OJPEG_SUPPORT + if ((tif->tif_dir.td_compression == COMPRESSION_OJPEG) && + (isTiled(tif) == 0) && (tif->tif_dir.td_nstrips == 1)) + { + /* + * XXX: OJPEG hack. + * If a) compression is OJPEG, b) it's not a tiled TIFF, + * and c) the number of strips is 1, + * then we tolerate the absence of stripoffsets tag, + * because, presumably, all required data is in the + * JpegInterchangeFormat stream. + */ + TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); + } + else #endif + { + MissingRequired(tif, isTiled(tif) ? "TileOffsets" : "StripOffsets"); + goto bad; + } + } - /* - * An opportunity for compression mode dependent tag fixup - */ - (*tif->tif_fixuptags)(tif); - - /* - * Some manufacturers make life difficult by writing - * large amounts of uncompressed data as a single strip. - * This is contrary to the recommendations of the spec. - * The following makes an attempt at breaking such images - * into strips closer to the recommended 8k bytes. A - * side effect, however, is that the RowsPerStrip tag - * value may be changed. - */ - if ((tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&& - (tif->tif_dir.td_nstrips==1)&& - (tif->tif_dir.td_compression==COMPRESSION_NONE)&& - ((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP)) + if (tif->tif_mode == O_RDWR && + tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && + tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) + { + /* Directory typically created with TIFFDeferStrileArrayWriting() */ + TIFFSetupStrips(tif); + } + else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD)) + { + if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0) { - ChopUpSingleUncompressedStrip(tif); + if (!TIFFFetchStripThing(tif, &(tif->tif_dir.td_stripoffset_entry), + tif->tif_dir.td_nstrips, + &tif->tif_dir.td_stripoffset_p)) + { + goto bad; + } } + if (tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0) + { + if (!TIFFFetchStripThing( + tif, &(tif->tif_dir.td_stripbytecount_entry), + tif->tif_dir.td_nstrips, &tif->tif_dir.td_stripbytecount_p)) + { + goto bad; + } + } + } - /* There are also uncompressed striped files with strips larger than */ - /* 2 GB, which make them unfriendly with a lot of code. If possible, */ - /* try to expose smaller "virtual" strips. */ - if( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && - tif->tif_dir.td_compression == COMPRESSION_NONE && - (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP && - TIFFStripSize64(tif) > 0x7FFFFFFFUL ) + /* + * Make sure all non-color channels are extrasamples. + * If it's not the case, define them as such. + */ + color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric); + if (color_channels && + tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > + color_channels) + { + uint16_t old_extrasamples; + uint16_t *new_sampleinfo; + + TIFFWarningExtR( + tif, module, + "Sum of Photometric type-related " + "color channels and ExtraSamples doesn't match SamplesPerPixel. " + "Defining non-color channels as ExtraSamples."); + + old_extrasamples = tif->tif_dir.td_extrasamples; + tif->tif_dir.td_extrasamples = + (uint16_t)(tif->tif_dir.td_samplesperpixel - color_channels); + + // sampleinfo should contain information relative to these new extra + // samples + new_sampleinfo = (uint16_t *)_TIFFcallocExt( + tif, tif->tif_dir.td_extrasamples, sizeof(uint16_t)); + if (!new_sampleinfo) { - TryChopUpUncompressedBigTiff(tif); + TIFFErrorExtR(tif, module, + "Failed to allocate memory for " + "temporary new sampleinfo array " + "(%" PRIu16 " 16 bit elements)", + tif->tif_dir.td_extrasamples); + goto bad; } + if (old_extrasamples > 0) + memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, + old_extrasamples * sizeof(uint16_t)); + _TIFFsetShortArrayExt(tif, &tif->tif_dir.td_sampleinfo, new_sampleinfo, + tif->tif_dir.td_extrasamples); + _TIFFfreeExt(tif, new_sampleinfo); + } + + /* + * Verify Palette image has a Colormap. + */ + if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE && + !TIFFFieldSet(tif, FIELD_COLORMAP)) + { + if (tif->tif_dir.td_bitspersample >= 8 && + tif->tif_dir.td_samplesperpixel == 3) + tif->tif_dir.td_photometric = PHOTOMETRIC_RGB; + else if (tif->tif_dir.td_bitspersample >= 8) + tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK; + else + { + MissingRequired(tif, "Colormap"); + goto bad; + } + } + /* + * OJPEG hack: + * We do no further messing with strip/tile offsets/bytecounts in OJPEG + * TIFFs + */ + if (tif->tif_dir.td_compression != COMPRESSION_OJPEG) + { /* - * Clear the dirty directory flag. + * Attempt to deal with a missing StripByteCounts tag. */ - tif->tif_flags &= ~TIFF_DIRTYDIRECT; - tif->tif_flags &= ~TIFF_DIRTYSTRIP; - - /* - * Reinitialize i/o since we are starting on a new directory. - */ - tif->tif_row = (uint32_t) -1; - tif->tif_curstrip = (uint32_t) -1; - tif->tif_col = (uint32_t) -1; - tif->tif_curtile = (uint32_t) -1; - tif->tif_tilesize = (tmsize_t) -1; - - tif->tif_scanlinesize = TIFFScanlineSize(tif); - if (!tif->tif_scanlinesize) { - TIFFErrorExtR(tif, module, - "Cannot handle zero scanline size"); - return (0); - } - - if (isTiled(tif)) { - tif->tif_tilesize = TIFFTileSize(tif); - if (!tif->tif_tilesize) { - TIFFErrorExtR(tif, module, - "Cannot handle zero tile size"); - return (0); - } - } else { - if (!TIFFStripSize(tif)) { - TIFFErrorExtR(tif, module, - "Cannot handle zero strip size"); - return (0); - } - } - return (1); + if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) + { + /* + * Some manufacturers violate the spec by not giving + * the size of the strips. In this case, assume there + * is one uncompressed strip of data. + */ + if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && + tif->tif_dir.td_nstrips > 1) || + (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE && + tif->tif_dir.td_nstrips != + (uint32_t)tif->tif_dir.td_samplesperpixel)) + { + MissingRequired(tif, "StripByteCounts"); + goto bad; + } + TIFFWarningExtR( + tif, module, + "TIFF directory is missing required " + "\"StripByteCounts\" field, calculating from imagelength"); + if (EstimateStripByteCounts(tif, dir, dircount) < 0) + goto bad; + } + else if (tif->tif_dir.td_nstrips == 1 && + !(tif->tif_flags & TIFF_ISTILED) && ByteCountLooksBad(tif)) + { + /* + * XXX: Plexus (and others) sometimes give a value of + * zero for a tag when they don't know what the + * correct value is! Try and handle the simple case + * of estimating the size of a one strip image. + */ + TIFFWarningExtR(tif, module, + "Bogus \"StripByteCounts\" field, ignoring and " + "calculating from imagelength"); + if (EstimateStripByteCounts(tif, dir, dircount) < 0) + goto bad; + } + else if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && + tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && + tif->tif_dir.td_nstrips > 2 && + tif->tif_dir.td_compression == COMPRESSION_NONE && + TIFFGetStrileByteCount(tif, 0) != + TIFFGetStrileByteCount(tif, 1) && + TIFFGetStrileByteCount(tif, 0) != 0 && + TIFFGetStrileByteCount(tif, 1) != 0) + { + /* + * XXX: Some vendors fill StripByteCount array with + * absolutely wrong values (it can be equal to + * StripOffset array, for example). Catch this case + * here. + * + * We avoid this check if deferring strile loading + * as it would always force us to load the strip/tile + * information. + */ + TIFFWarningExtR(tif, module, + "Wrong \"StripByteCounts\" field, ignoring and " + "calculating from imagelength"); + if (EstimateStripByteCounts(tif, dir, dircount) < 0) + goto bad; + } + } + if (dir) + { + _TIFFfreeExt(tif, dir); + dir = NULL; + } + if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) + { + if (tif->tif_dir.td_bitspersample >= 16) + tif->tif_dir.td_maxsamplevalue = 0xFFFF; + else + tif->tif_dir.td_maxsamplevalue = + (uint16_t)((1L << tif->tif_dir.td_bitspersample) - 1); + } + +#ifdef STRIPBYTECOUNTSORTED_UNUSED + /* + * XXX: We can optimize checking for the strip bounds using the sorted + * bytecounts array. See also comments for TIFFAppendToStrip() + * function in tif_write.c. + */ + if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1) + { + uint32_t strip; + + tif->tif_dir.td_stripbytecountsorted = 1; + for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) + { + if (TIFFGetStrileOffset(tif, strip - 1) > + TIFFGetStrileOffset(tif, strip)) + { + tif->tif_dir.td_stripbytecountsorted = 0; + break; + } + } + } +#endif + + /* + * An opportunity for compression mode dependent tag fixup + */ + (*tif->tif_fixuptags)(tif); + + /* + * Some manufacturers make life difficult by writing + * large amounts of uncompressed data as a single strip. + * This is contrary to the recommendations of the spec. + * The following makes an attempt at breaking such images + * into strips closer to the recommended 8k bytes. A + * side effect, however, is that the RowsPerStrip tag + * value may be changed. + */ + if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) && + (tif->tif_dir.td_nstrips == 1) && + (tif->tif_dir.td_compression == COMPRESSION_NONE) && + ((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP)) + { + ChopUpSingleUncompressedStrip(tif); + } + + /* There are also uncompressed striped files with strips larger than */ + /* 2 GB, which make them unfriendly with a lot of code. If possible, */ + /* try to expose smaller "virtual" strips. */ + if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG && + tif->tif_dir.td_compression == COMPRESSION_NONE && + (tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == TIFF_STRIPCHOP && + TIFFStripSize64(tif) > 0x7FFFFFFFUL) + { + TryChopUpUncompressedBigTiff(tif); + } + + /* + * Clear the dirty directory flag. + */ + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + + /* + * Reinitialize i/o since we are starting on a new directory. + */ + tif->tif_row = (uint32_t)-1; + tif->tif_curstrip = (uint32_t)-1; + tif->tif_col = (uint32_t)-1; + tif->tif_curtile = (uint32_t)-1; + tif->tif_tilesize = (tmsize_t)-1; + + tif->tif_scanlinesize = TIFFScanlineSize(tif); + if (!tif->tif_scanlinesize) + { + TIFFErrorExtR(tif, module, "Cannot handle zero scanline size"); + return (0); + } + + if (isTiled(tif)) + { + tif->tif_tilesize = TIFFTileSize(tif); + if (!tif->tif_tilesize) + { + TIFFErrorExtR(tif, module, "Cannot handle zero tile size"); + return (0); + } + } + else + { + if (!TIFFStripSize(tif)) + { + TIFFErrorExtR(tif, module, "Cannot handle zero strip size"); + return (0); + } + } + return (1); bad: - if (dir) - _TIFFfreeExt(tif, dir); - return (0); + if (dir) + _TIFFfreeExt(tif, dir); + return (0); } -static void -TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16_t dircount) +static void TIFFReadDirectoryCheckOrder(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount) { - static const char module[] = "TIFFReadDirectoryCheckOrder"; - uint16_t m; - uint16_t n; - TIFFDirEntry* o; - m=0; - for (n=0, o=dir; n<dircount; n++, o++) - { - if (o->tdir_tag<m) - { - TIFFWarningExtR(tif,module, - "Invalid TIFF directory; tags are not sorted in ascending order"); - break; - } - m=o->tdir_tag+1; - } + static const char module[] = "TIFFReadDirectoryCheckOrder"; + uint16_t m; + uint16_t n; + TIFFDirEntry *o; + m = 0; + for (n = 0, o = dir; n < dircount; n++, o++) + { + if (o->tdir_tag < m) + { + TIFFWarningExtR(tif, module, + "Invalid TIFF directory; tags are not sorted in " + "ascending order"); + break; + } + m = o->tdir_tag + 1; + } } -static TIFFDirEntry* -TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16_t dircount, uint16_t tagid) +static TIFFDirEntry *TIFFReadDirectoryFindEntry(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount, + uint16_t tagid) { - TIFFDirEntry* m; - uint16_t n; - (void) tif; - for (m=dir, n=0; n<dircount; m++, n++) - { - if (m->tdir_tag==tagid) - return(m); - } - return(0); + TIFFDirEntry *m; + uint16_t n; + (void)tif; + for (m = dir, n = 0; n < dircount; m++, n++) + { + if (m->tdir_tag == tagid) + return (m); + } + return (0); } -static void -TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16_t tagid, uint32_t* fii) +static void TIFFReadDirectoryFindFieldInfo(TIFF *tif, uint16_t tagid, + uint32_t *fii) { - int32_t ma,mb,mc; - ma=-1; - mc=(int32_t)tif->tif_nfields; - while (1) - { - if (ma+1==mc) - { - *fii = FAILED_FII; - return; - } - mb=(ma+mc)/2; - if (tif->tif_fields[mb]->field_tag==(uint32_t)tagid) - break; - if (tif->tif_fields[mb]->field_tag<(uint32_t)tagid) - ma=mb; - else - mc=mb; - } - while (1) - { - if (mb==0) - break; - if (tif->tif_fields[mb-1]->field_tag!=(uint32_t)tagid) - break; - mb--; - } - *fii=mb; + int32_t ma, mb, mc; + ma = -1; + mc = (int32_t)tif->tif_nfields; + while (1) + { + if (ma + 1 == mc) + { + *fii = FAILED_FII; + return; + } + mb = (ma + mc) / 2; + if (tif->tif_fields[mb]->field_tag == (uint32_t)tagid) + break; + if (tif->tif_fields[mb]->field_tag < (uint32_t)tagid) + ma = mb; + else + mc = mb; + } + while (1) + { + if (mb == 0) + break; + if (tif->tif_fields[mb - 1]->field_tag != (uint32_t)tagid) + break; + mb--; + } + *fii = mb; } /* * Read custom directory from the arbitrary offset. * The code is very similar to TIFFReadDirectory(). */ -int -TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, - const TIFFFieldArray* infoarray) +int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, + const TIFFFieldArray *infoarray) { - static const char module[] = "TIFFReadCustomDirectory"; - TIFFDirEntry* dir; - uint16_t dircount; - TIFFDirEntry* dp; - uint16_t di; - const TIFFField* fip; - uint32_t fii; - (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ - _TIFFSetupFields(tif, infoarray); - dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL); - if (!dircount) - { - TIFFErrorExtR(tif,module, - "Failed to read custom directory at offset %" PRIu64,diroff); - return 0; - } - TIFFFreeDirectory(tif); - _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory)); - TIFFReadDirectoryCheckOrder(tif,dir,dircount); - for (di=0, dp=dir; di<dircount; di++, dp++) - { - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - if (fii == FAILED_FII) - { - TIFFWarningExtR(tif, module, - "Unknown field with tag %"PRIu16" (0x%"PRIx16") encountered", - dp->tdir_tag, dp->tdir_tag); - if (!_TIFFMergeFields(tif, _TIFFCreateAnonField(tif, - dp->tdir_tag, - (TIFFDataType) dp->tdir_type), - 1)) { - TIFFWarningExtR(tif, module, - "Registering anonymous field with tag %"PRIu16" (0x%"PRIx16") failed", - dp->tdir_tag, dp->tdir_tag); - dp->tdir_ignore = TRUE; - } else { - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - assert( fii != FAILED_FII ); - } - } - if (!dp->tdir_ignore) - { - fip=tif->tif_fields[fii]; - if (fip->field_bit==FIELD_IGNORE) - dp->tdir_ignore = TRUE; - else - { - /* check data type */ - while ((fip->field_type!=TIFF_ANY)&&(fip->field_type!=dp->tdir_type)) - { - fii++; - if ((fii==tif->tif_nfields)|| - (tif->tif_fields[fii]->field_tag!=(uint32_t)dp->tdir_tag)) - { - fii=0xFFFF; - break; - } - fip=tif->tif_fields[fii]; - } - if (fii==0xFFFF) - { - TIFFWarningExtR(tif, module, - "Wrong data type %"PRIu16" for \"%s\"; tag ignored", - dp->tdir_type,fip->field_name); - dp->tdir_ignore = TRUE; - } - else - { - /* check count if known in advance */ - if ((fip->field_readcount!=TIFF_VARIABLE)&& - (fip->field_readcount!=TIFF_VARIABLE2)) - { - uint32_t expected; - if (fip->field_readcount==TIFF_SPP) - expected=(uint32_t)tif->tif_dir.td_samplesperpixel; - else - expected=(uint32_t)fip->field_readcount; - if (!CheckDirCount(tif,dp,expected)) - dp->tdir_ignore = TRUE; - } - } - } - if (!dp->tdir_ignore) { - switch (dp->tdir_tag) - { - case EXIFTAG_SUBJECTDISTANCE: - if(!TIFFFieldIsAnonymous(fip)) { + static const char module[] = "TIFFReadCustomDirectory"; + TIFFDirEntry *dir; + uint16_t dircount; + TIFFDirEntry *dp; + uint16_t di; + const TIFFField *fip; + uint32_t fii; + (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */ + _TIFFSetupFields(tif, infoarray); + dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL); + if (!dircount) + { + TIFFErrorExtR(tif, module, + "Failed to read custom directory at offset %" PRIu64, + diroff); + return 0; + } + TIFFFreeDirectory(tif); + _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory)); + TIFFReadDirectoryCheckOrder(tif, dir, dircount); + for (di = 0, dp = dir; di < dircount; di++, dp++) + { + TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); + if (fii == FAILED_FII) + { + TIFFWarningExtR(tif, module, + "Unknown field with tag %" PRIu16 " (0x%" PRIx16 + ") encountered", + dp->tdir_tag, dp->tdir_tag); + if (!_TIFFMergeFields( + tif, + _TIFFCreateAnonField(tif, dp->tdir_tag, + (TIFFDataType)dp->tdir_type), + 1)) + { + TIFFWarningExtR(tif, module, + "Registering anonymous field with tag %" PRIu16 + " (0x%" PRIx16 ") failed", + dp->tdir_tag, dp->tdir_tag); + dp->tdir_ignore = TRUE; + } + else + { + TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); + assert(fii != FAILED_FII); + } + } + if (!dp->tdir_ignore) + { + fip = tif->tif_fields[fii]; + if (fip->field_bit == FIELD_IGNORE) + dp->tdir_ignore = TRUE; + else + { + /* check data type */ + while ((fip->field_type != TIFF_ANY) && + (fip->field_type != dp->tdir_type)) + { + fii++; + if ((fii == tif->tif_nfields) || + (tif->tif_fields[fii]->field_tag != + (uint32_t)dp->tdir_tag)) + { + fii = 0xFFFF; + break; + } + fip = tif->tif_fields[fii]; + } + if (fii == 0xFFFF) + { + TIFFWarningExtR(tif, module, + "Wrong data type %" PRIu16 + " for \"%s\"; tag ignored", + dp->tdir_type, fip->field_name); + dp->tdir_ignore = TRUE; + } + else + { + /* check count if known in advance */ + if ((fip->field_readcount != TIFF_VARIABLE) && + (fip->field_readcount != TIFF_VARIABLE2)) + { + uint32_t expected; + if (fip->field_readcount == TIFF_SPP) + expected = + (uint32_t)tif->tif_dir.td_samplesperpixel; + else + expected = (uint32_t)fip->field_readcount; + if (!CheckDirCount(tif, dp, expected)) + dp->tdir_ignore = TRUE; + } + } + } + if (!dp->tdir_ignore) + { + switch (dp->tdir_tag) + { + case EXIFTAG_SUBJECTDISTANCE: + if (!TIFFFieldIsAnonymous(fip)) + { /* should only be called on a Exif directory */ /* when exifFields[] is active */ (void)TIFFFetchSubjectDistance(tif, dp); } - else { + else + { (void)TIFFFetchNormalTag(tif, dp, TRUE); } - break; - default: - (void)TIFFFetchNormalTag(tif, dp, TRUE); - break; - } - } /*-- if (!dp->tdir_ignore) */ - } - } - if (dir) - _TIFFfreeExt(tif, dir); - return 1; + break; + default: + (void)TIFFFetchNormalTag(tif, dp, TRUE); + break; + } + } /*-- if (!dp->tdir_ignore) */ + } + } + if (dir) + _TIFFfreeExt(tif, dir); + return 1; } /* * EXIF is important special case of custom IFD, so we have a special * function to read it. */ -int -TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff) +int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff) { - const TIFFFieldArray* exifFieldArray; - exifFieldArray = _TIFFGetExifFields(); - return TIFFReadCustomDirectory(tif, diroff, exifFieldArray); + const TIFFFieldArray *exifFieldArray; + exifFieldArray = _TIFFGetExifFields(); + return TIFFReadCustomDirectory(tif, diroff, exifFieldArray); } /* *--: EXIF-GPS custom directory reading as another special case of custom IFD. */ -int -TIFFReadGPSDirectory(TIFF* tif, toff_t diroff) +int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff) { - const TIFFFieldArray* gpsFieldArray; - gpsFieldArray = _TIFFGetGpsFields(); - return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray); + const TIFFFieldArray *gpsFieldArray; + gpsFieldArray = _TIFFGetGpsFields(); + return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray); } -static int -EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16_t dircount) +static int EstimateStripByteCounts(TIFF *tif, TIFFDirEntry *dir, + uint16_t dircount) { - static const char module[] = "EstimateStripByteCounts"; + static const char module[] = "EstimateStripByteCounts"; - TIFFDirEntry *dp; - TIFFDirectory *td = &tif->tif_dir; - uint32_t strip; + TIFFDirEntry *dp; + TIFFDirectory *td = &tif->tif_dir; + uint32_t strip; /* Do not try to load stripbytecount as we will compute it */ - if( !_TIFFFillStrilesInternal( tif, 0 ) ) - return -1; + if (!_TIFFFillStrilesInternal(tif, 0)) + return -1; + + if (td->td_stripbytecount_p) + _TIFFfreeExt(tif, td->td_stripbytecount_p); + td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc( + tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array"); + if (td->td_stripbytecount_p == NULL) + return -1; - if (td->td_stripbytecount_p) - _TIFFfreeExt(tif, td->td_stripbytecount_p); - td->td_stripbytecount_p = (uint64_t*) - _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64_t), - "for \"StripByteCounts\" array"); - if( td->td_stripbytecount_p == NULL ) + if (td->td_compression != COMPRESSION_NONE) + { + uint64_t space; + uint64_t filesize; + uint16_t n; + filesize = TIFFGetFileSize(tif); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + space = sizeof(TIFFHeaderClassic) + 2 + dircount * 12 + 4; + else + space = sizeof(TIFFHeaderBig) + 8 + dircount * 20 + 8; + /* calculate amount of space used by indirect values */ + for (dp = dir, n = dircount; n > 0; n--, dp++) + { + uint32_t typewidth; + uint64_t datasize; + typewidth = TIFFDataWidth((TIFFDataType)dp->tdir_type); + if (typewidth == 0) + { + TIFFErrorExtR( + tif, module, + "Cannot determine size of unknown tag type %" PRIu16, + dp->tdir_type); + return -1; + } + if (dp->tdir_count > UINT64_MAX / typewidth) + return -1; + datasize = (uint64_t)typewidth * dp->tdir_count; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + if (datasize <= 4) + datasize = 0; + } + else + { + if (datasize <= 8) + datasize = 0; + } + if (space > UINT64_MAX - datasize) + return -1; + space += datasize; + } + if (filesize < space) + /* we should perhaps return in error ? */ + space = filesize; + else + space = filesize - space; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + space /= td->td_samplesperpixel; + for (strip = 0; strip < td->td_nstrips; strip++) + td->td_stripbytecount_p[strip] = space; + /* + * This gross hack handles the case were the offset to + * the last strip is past the place where we think the strip + * should begin. Since a strip of data must be contiguous, + * it's safe to assume that we've overestimated the amount + * of data in the strip and trim this number back accordingly. + */ + strip--; + if (td->td_stripoffset_p[strip] > + UINT64_MAX - td->td_stripbytecount_p[strip]) return -1; + if (td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip] > + filesize) + { + if (td->td_stripoffset_p[strip] >= filesize) + { + /* Not sure what we should in that case... */ + td->td_stripbytecount_p[strip] = 0; + } + else + { + td->td_stripbytecount_p[strip] = + filesize - td->td_stripoffset_p[strip]; + } + } + } + else if (isTiled(tif)) + { + uint64_t bytespertile = TIFFTileSize64(tif); - if (td->td_compression != COMPRESSION_NONE) { - uint64_t space; - uint64_t filesize; - uint16_t n; - filesize = TIFFGetFileSize(tif); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - space=sizeof(TIFFHeaderClassic)+2+dircount*12+4; - else - space=sizeof(TIFFHeaderBig)+8+dircount*20+8; - /* calculate amount of space used by indirect values */ - for (dp = dir, n = dircount; n > 0; n--, dp++) - { - uint32_t typewidth; - uint64_t datasize; - typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type); - if (typewidth == 0) { - TIFFErrorExtR(tif, module, - "Cannot determine size of unknown tag type %"PRIu16, - dp->tdir_type); - return -1; - } - if( dp->tdir_count > UINT64_MAX / typewidth ) - return -1; - datasize= (uint64_t)typewidth * dp->tdir_count; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (datasize<=4) - datasize=0; - } - else - { - if (datasize<=8) - datasize=0; - } - if( space > UINT64_MAX - datasize ) - return -1; - space+=datasize; - } - if( filesize < space ) - /* we should perhaps return in error ? */ - space = filesize; - else - space = filesize - space; - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - space /= td->td_samplesperpixel; - for (strip = 0; strip < td->td_nstrips; strip++) - td->td_stripbytecount_p[strip] = space; - /* - * This gross hack handles the case were the offset to - * the last strip is past the place where we think the strip - * should begin. Since a strip of data must be contiguous, - * it's safe to assume that we've overestimated the amount - * of data in the strip and trim this number back accordingly. - */ - strip--; - if (td->td_stripoffset_p[strip] > UINT64_MAX - td->td_stripbytecount_p[strip]) - return -1; - if (td->td_stripoffset_p[strip]+td->td_stripbytecount_p[strip] > filesize) { - if( td->td_stripoffset_p[strip] >= filesize ) { - /* Not sure what we should in that case... */ - td->td_stripbytecount_p[strip] = 0; - } else { - td->td_stripbytecount_p[strip] = filesize - td->td_stripoffset_p[strip]; - } - } - } else if (isTiled(tif)) { - uint64_t bytespertile = TIFFTileSize64(tif); - - for (strip = 0; strip < td->td_nstrips; strip++) - td->td_stripbytecount_p[strip] = bytespertile; - } else { - uint64_t rowbytes = TIFFScanlineSize64(tif); - uint32_t rowsperstrip = td->td_imagelength / td->td_stripsperimage; - for (strip = 0; strip < td->td_nstrips; strip++) - { - if( rowbytes > 0 && rowsperstrip > UINT64_MAX / rowbytes ) - return -1; - td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip; - } - } - TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); - if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) - td->td_rowsperstrip = td->td_imagelength; - return 1; + for (strip = 0; strip < td->td_nstrips; strip++) + td->td_stripbytecount_p[strip] = bytespertile; + } + else + { + uint64_t rowbytes = TIFFScanlineSize64(tif); + uint32_t rowsperstrip = td->td_imagelength / td->td_stripsperimage; + for (strip = 0; strip < td->td_nstrips; strip++) + { + if (rowbytes > 0 && rowsperstrip > UINT64_MAX / rowbytes) + return -1; + td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip; + } + } + TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); + if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) + td->td_rowsperstrip = td->td_imagelength; + return 1; } -static void -MissingRequired(TIFF* tif, const char* tagname) +static void MissingRequired(TIFF *tif, const char *tagname) { - static const char module[] = "MissingRequired"; + static const char module[] = "MissingRequired"; - TIFFErrorExtR(tif, module, - "TIFF directory is missing required \"%s\" field", - tagname); + TIFFErrorExtR(tif, module, + "TIFF directory is missing required \"%s\" field", tagname); } /* @@ -5015,77 +5290,96 @@ MissingRequired(TIFF* tif, const char* tagname) * Returns 1 if all is ok; 0 if last directory or IFD loop is encountered, * or an error has occurred. */ -int -_TIFFCheckDirNumberAndOffset(TIFF *tif, uint16_t dirn, uint64_t diroff) +int _TIFFCheckDirNumberAndOffset(TIFF *tif, uint16_t dirn, uint64_t diroff) { - uint16_t n; - - if (diroff == 0) /* no more directories */ - return 0; - if (tif->tif_dirnumber == 65535) { - TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", - "Cannot handle more than 65535 TIFF directories"); - return 0; - } - - /* Check if offset is already in the list: - * - yes: check, if offset is at the same IFD number - if not, it is an IFD loop - * - no: add to list or update offset at that IFD number - */ - for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlistdirn && tif->tif_dirlistoff; n++) { - if (tif->tif_dirlistoff[n] == diroff) { - if (tif->tif_dirlistdirn[n] == dirn) { - return 1; - } else { - TIFFWarningExtR(tif, "_TIFFCheckDirNumberAndOffset", - "TIFF directory %d has IFD looping to directory %"PRIu16" at offset 0x%"PRIx64" (%"PRIu64")", - (int)dirn-1, tif->tif_dirlistdirn[n], diroff, diroff); - return 0; - } - } - } - /* Check if offset of an IFD has been changed and update offset of that IFD number. */ - if (dirn < tif->tif_dirnumber && tif->tif_dirlistdirn && tif->tif_dirlistoff) { - /* tif_dirlistdirn can have IFD numbers dirn in random order */ - for (n = 0; n < tif->tif_dirnumber; n++) { - if (tif->tif_dirlistdirn[n] == dirn) { - tif->tif_dirlistoff[n] = diroff; - return 1; - } - } - } - - /* Add IFD offset and dirn to IFD directory list */ - tif->tif_dirnumber++; - - if (tif->tif_dirlistoff == NULL || tif->tif_dirlistdirn == NULL || tif->tif_dirnumber > tif->tif_dirlistsize) { - uint64_t *new_dirlist; - /* - * XXX: Reduce memory allocation granularity of the dirlist - * array. - */ - if (tif->tif_dirnumber >= 32768) - tif->tif_dirlistsize = 65535; - else - tif->tif_dirlistsize = 2 * tif->tif_dirnumber; - - new_dirlist = (uint64_t *)_TIFFCheckRealloc(tif, tif->tif_dirlistoff, - tif->tif_dirlistsize, sizeof(uint64_t), "for IFD offset list"); - if (!new_dirlist) - return 0; - tif->tif_dirlistoff = new_dirlist; - new_dirlist = (uint64_t *)_TIFFCheckRealloc(tif, tif->tif_dirlistdirn, - tif->tif_dirlistsize, sizeof(uint16_t), "for IFD dirnumber list"); - if (!new_dirlist) - return 0; - tif->tif_dirlistdirn = (uint16_t *)new_dirlist; - } - - tif->tif_dirlistoff[tif->tif_dirnumber - 1] = diroff; - tif->tif_dirlistdirn[tif->tif_dirnumber - 1] = dirn; - - return 1; -} /* --- _TIFFCheckDirNumberAndOffset() ---*/ + uint16_t n; + + if (diroff == 0) /* no more directories */ + return 0; + if (tif->tif_dirnumber == 65535) + { + TIFFErrorExtR(tif, "_TIFFCheckDirNumberAndOffset", + "Cannot handle more than 65535 TIFF directories"); + return 0; + } + + /* Check if offset is already in the list: + * - yes: check, if offset is at the same IFD number - if not, it is an IFD + * loop + * - no: add to list or update offset at that IFD number + */ + for (n = 0; + n < tif->tif_dirnumber && tif->tif_dirlistdirn && tif->tif_dirlistoff; + n++) + { + if (tif->tif_dirlistoff[n] == diroff) + { + if (tif->tif_dirlistdirn[n] == dirn) + { + return 1; + } + else + { + TIFFWarningExtR( + tif, "_TIFFCheckDirNumberAndOffset", + "TIFF directory %d has IFD looping to directory %" PRIu16 + " at offset 0x%" PRIx64 " (%" PRIu64 ")", + (int)dirn - 1, tif->tif_dirlistdirn[n], diroff, diroff); + return 0; + } + } + } + /* Check if offset of an IFD has been changed and update offset of that IFD + * number. */ + if (dirn < tif->tif_dirnumber && tif->tif_dirlistdirn && + tif->tif_dirlistoff) + { + /* tif_dirlistdirn can have IFD numbers dirn in random order */ + for (n = 0; n < tif->tif_dirnumber; n++) + { + if (tif->tif_dirlistdirn[n] == dirn) + { + tif->tif_dirlistoff[n] = diroff; + return 1; + } + } + } + + /* Add IFD offset and dirn to IFD directory list */ + tif->tif_dirnumber++; + + if (tif->tif_dirlistoff == NULL || tif->tif_dirlistdirn == NULL || + tif->tif_dirnumber > tif->tif_dirlistsize) + { + uint64_t *new_dirlist; + /* + * XXX: Reduce memory allocation granularity of the dirlist + * array. + */ + if (tif->tif_dirnumber >= 32768) + tif->tif_dirlistsize = 65535; + else + tif->tif_dirlistsize = 2 * tif->tif_dirnumber; + + new_dirlist = (uint64_t *)_TIFFCheckRealloc( + tif, tif->tif_dirlistoff, tif->tif_dirlistsize, sizeof(uint64_t), + "for IFD offset list"); + if (!new_dirlist) + return 0; + tif->tif_dirlistoff = new_dirlist; + new_dirlist = (uint64_t *)_TIFFCheckRealloc( + tif, tif->tif_dirlistdirn, tif->tif_dirlistsize, sizeof(uint16_t), + "for IFD dirnumber list"); + if (!new_dirlist) + return 0; + tif->tif_dirlistdirn = (uint16_t *)new_dirlist; + } + + tif->tif_dirlistoff[tif->tif_dirnumber - 1] = diroff; + tif->tif_dirlistdirn[tif->tif_dirnumber - 1] = dirn; + + return 1; +} /* --- _TIFFCheckDirNumberAndOffset() ---*/ /* * Retrieve the matching IFD directory number of a given IFD offset @@ -5094,64 +5388,75 @@ _TIFFCheckDirNumberAndOffset(TIFF *tif, uint16_t dirn, uint64_t diroff) * can be returned. * Otherwise returns 0 or if an error occurred. */ -int -_TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, uint16_t* dirn) +int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64_t diroff, uint16_t *dirn) { - uint16_t n; - - if (diroff == 0) /* no more directories */ - return 0; - if (tif->tif_dirnumber == 65535) { - TIFFErrorExtR(tif, "_TIFFGetDirNumberFromOffset", - "Cannot handle more than 65535 TIFF directories"); - return 0; - } - - /* Check if offset is already in the list and return matching directory number. - * Otherwise update IFD list using TIFFNumberOfDirectories() - * and search again in IFD list. - */ - for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlistoff && tif->tif_dirlistdirn; n++) { - if (tif->tif_dirlistoff[n] == diroff) { - *dirn = tif->tif_dirlistdirn[n]; - return 1; - } - } - TIFFNumberOfDirectories(tif); - for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlistoff && tif->tif_dirlistdirn; n++) { - if (tif->tif_dirlistoff[n] == diroff) { - *dirn = tif->tif_dirlistdirn[n]; - return 1; - } - } - return 0; -} /*--- _TIFFGetDirNumberFromOffset() ---*/ + uint16_t n; + if (diroff == 0) /* no more directories */ + return 0; + if (tif->tif_dirnumber == 65535) + { + TIFFErrorExtR(tif, "_TIFFGetDirNumberFromOffset", + "Cannot handle more than 65535 TIFF directories"); + return 0; + } + + /* Check if offset is already in the list and return matching directory + * number. Otherwise update IFD list using TIFFNumberOfDirectories() and + * search again in IFD list. + */ + for (n = 0; + n < tif->tif_dirnumber && tif->tif_dirlistoff && tif->tif_dirlistdirn; + n++) + { + if (tif->tif_dirlistoff[n] == diroff) + { + *dirn = tif->tif_dirlistdirn[n]; + return 1; + } + } + TIFFNumberOfDirectories(tif); + for (n = 0; + n < tif->tif_dirnumber && tif->tif_dirlistoff && tif->tif_dirlistdirn; + n++) + { + if (tif->tif_dirlistoff[n] == diroff) + { + *dirn = tif->tif_dirlistdirn[n]; + return 1; + } + } + return 0; +} /*--- _TIFFGetDirNumberFromOffset() ---*/ /* * Check the count field of a directory entry against a known value. The * caller is expected to skip/ignore the tag if there is a mismatch. */ -static int -CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32_t count) +static int CheckDirCount(TIFF *tif, TIFFDirEntry *dir, uint32_t count) { - if ((uint64_t)count > dir->tdir_count) { - const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag); - TIFFWarningExtR(tif, tif->tif_name, - "incorrect count for field \"%s\" (%" PRIu64 ", expecting %"PRIu32"); tag ignored", - fip ? fip->field_name : "unknown tagname", - dir->tdir_count, count); - return (0); - } else if ((uint64_t)count < dir->tdir_count) { - const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag); - TIFFWarningExtR(tif, tif->tif_name, - "incorrect count for field \"%s\" (%" PRIu64 ", expecting %"PRIu32"); tag trimmed", - fip ? fip->field_name : "unknown tagname", - dir->tdir_count, count); - dir->tdir_count = count; - return (1); - } - return (1); + if ((uint64_t)count > dir->tdir_count) + { + const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFWarningExtR(tif, tif->tif_name, + "incorrect count for field \"%s\" (%" PRIu64 + ", expecting %" PRIu32 "); tag ignored", + fip ? fip->field_name : "unknown tagname", + dir->tdir_count, count); + return (0); + } + else if ((uint64_t)count < dir->tdir_count) + { + const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFWarningExtR(tif, tif->tif_name, + "incorrect count for field \"%s\" (%" PRIu64 + ", expecting %" PRIu32 "); tag trimmed", + fip ? fip->field_name : "unknown tagname", + dir->tdir_count, count); + dir->tdir_count = count; + return (1); + } + return (1); } /* @@ -5159,1404 +5464,1511 @@ CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32_t count) * nextdiroff variable has been specified, read it too. Function returns a * number of fields in the directory or 0 if failed. */ -static uint16_t -TIFFFetchDirectory(TIFF* tif, uint64_t diroff, TIFFDirEntry** pdir, - uint64_t *nextdiroff) +static uint16_t TIFFFetchDirectory(TIFF *tif, uint64_t diroff, + TIFFDirEntry **pdir, uint64_t *nextdiroff) { - static const char module[] = "TIFFFetchDirectory"; - - void* origdir; - uint16_t dircount16; - uint32_t dirsize; - TIFFDirEntry* dir; - uint8_t* ma; - TIFFDirEntry* mb; - uint16_t n; - - assert(pdir); - - tif->tif_diroff = diroff; - if (nextdiroff) - *nextdiroff = 0; - if (!isMapped(tif)) { - if (!SeekOK(tif, tif->tif_diroff)) { - TIFFErrorExtR(tif, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); - return 0; - } - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (!ReadOK(tif, &dircount16, sizeof (uint16_t))) { - TIFFErrorExtR(tif, module, - "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount16); - if (dircount16>4096) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dirsize = 12; - } else { - uint64_t dircount64; - if (!ReadOK(tif, &dircount64, sizeof (uint64_t))) { - TIFFErrorExtR(tif, module, - "%s: Can not read TIFF directory count", - tif->tif_name); - return 0; - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>4096) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dircount16 = (uint16_t)dircount64; - dirsize = 20; - } - origdir = _TIFFCheckMalloc(tif, dircount16, - dirsize, "to read TIFF directory"); - if (origdir == NULL) - return 0; - if (!ReadOK(tif, origdir, (tmsize_t)(dircount16*dirsize))) { - TIFFErrorExtR(tif, module, - "%.100s: Can not read TIFF directory", - tif->tif_name); - _TIFFfreeExt(tif, origdir); - return 0; - } - /* - * Read offset to next directory for sequential scans if - * needed. - */ - if (nextdiroff) - { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32_t nextdiroff32; - if (!ReadOK(tif, &nextdiroff32, sizeof(uint32_t))) - nextdiroff32 = 0; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&nextdiroff32); - *nextdiroff=nextdiroff32; - } else { - if (!ReadOK(tif, nextdiroff, sizeof(uint64_t))) - *nextdiroff = 0; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - } else { - tmsize_t m; - tmsize_t off; - if (tif->tif_diroff > (uint64_t)INT64_MAX) - { - TIFFErrorExtR(tif,module,"Can not read TIFF directory count"); - return(0); - } - off = (tmsize_t) tif->tif_diroff; - - /* - * Check for integer overflow when validating the dir_off, - * otherwise a very high offset may cause an OOB read and - * crash the client. Make two comparisons instead of - * - * off + sizeof(uint16_t) > tif->tif_size - * - * to avoid overflow. - */ - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - m=off+sizeof(uint16_t); - if ((m<off) || (m<(tmsize_t)sizeof(uint16_t)) || (m > tif->tif_size)) { - TIFFErrorExtR(tif, module, - "Can not read TIFF directory count"); - return 0; - } else { - _TIFFmemcpy(&dircount16, tif->tif_base + off, - sizeof(uint16_t)); - } - off += sizeof (uint16_t); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount16); - if (dircount16>4096) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dirsize = 12; - } - else - { - uint64_t dircount64; - m=off+sizeof(uint64_t); - if ((m<off) || (m<(tmsize_t)sizeof(uint64_t)) || (m > tif->tif_size)) { - TIFFErrorExtR(tif, module, - "Can not read TIFF directory count"); - return 0; - } else { - _TIFFmemcpy(&dircount64, tif->tif_base + off, - sizeof(uint64_t)); - } - off += sizeof (uint64_t); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>4096) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed, this is probably not a valid IFD offset"); - return 0; - } - dircount16 = (uint16_t)dircount64; - dirsize = 20; - } - if (dircount16 == 0 ) - { - TIFFErrorExtR(tif, module, - "Sanity check on directory count failed, zero tag directories not supported"); - return 0; - } - origdir = _TIFFCheckMalloc(tif, dircount16, - dirsize, - "to read TIFF directory"); - if (origdir == NULL) - return 0; - m=off+dircount16*dirsize; - if ((m<off)||(m<(tmsize_t)(dircount16*dirsize))||(m>tif->tif_size)) { - TIFFErrorExtR(tif, module, - "Can not read TIFF directory"); - _TIFFfreeExt(tif, origdir); - return 0; - } else { - _TIFFmemcpy(origdir, tif->tif_base + off, - dircount16 * dirsize); - } - if (nextdiroff) { - off += dircount16 * dirsize; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32_t nextdiroff32; - m=off+sizeof(uint32_t); - if ((m<off) || (m<(tmsize_t)sizeof(uint32_t)) || (m > tif->tif_size)) - nextdiroff32 = 0; - else - _TIFFmemcpy(&nextdiroff32, tif->tif_base + off, - sizeof (uint32_t)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&nextdiroff32); - *nextdiroff = nextdiroff32; - } - else - { - m=off+sizeof(uint64_t); - if ((m<off) || (m<(tmsize_t)sizeof(uint64_t)) || (m > tif->tif_size)) - *nextdiroff = 0; - else - _TIFFmemcpy(nextdiroff, tif->tif_base + off, - sizeof (uint64_t)); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(nextdiroff); - } - } - } - dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16, - sizeof(TIFFDirEntry), - "to read TIFF directory"); - if (dir==0) - { - _TIFFfreeExt(tif, origdir); - return 0; - } - ma=(uint8_t*)origdir; - mb=dir; - for (n=0; n<dircount16; n++) - { - mb->tdir_ignore = FALSE; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)ma); - mb->tdir_tag=*(uint16_t*)ma; - ma+=sizeof(uint16_t); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)ma); - mb->tdir_type=*(uint16_t*)ma; - ma+=sizeof(uint16_t); - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)ma); - mb->tdir_count=(uint64_t)(*(uint32_t*)ma); - ma+=sizeof(uint32_t); - mb->tdir_offset.toff_long8=0; - *(uint32_t*)(&mb->tdir_offset)=*(uint32_t*)ma; - ma+=sizeof(uint32_t); - } - else - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)ma); - mb->tdir_count=TIFFReadUInt64(ma); - ma+=sizeof(uint64_t); - mb->tdir_offset.toff_long8=TIFFReadUInt64(ma); - ma+=sizeof(uint64_t); - } - mb++; - } - _TIFFfreeExt(tif, origdir); - *pdir = dir; - return dircount16; + static const char module[] = "TIFFFetchDirectory"; + + void *origdir; + uint16_t dircount16; + uint32_t dirsize; + TIFFDirEntry *dir; + uint8_t *ma; + TIFFDirEntry *mb; + uint16_t n; + + assert(pdir); + + tif->tif_diroff = diroff; + if (nextdiroff) + *nextdiroff = 0; + if (!isMapped(tif)) + { + if (!SeekOK(tif, tif->tif_diroff)) + { + TIFFErrorExtR(tif, module, + "%s: Seek error accessing TIFF directory", + tif->tif_name); + return 0; + } + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + if (!ReadOK(tif, &dircount16, sizeof(uint16_t))) + { + TIFFErrorExtR(tif, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount16); + if (dircount16 > 4096) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed, this is " + "probably not a valid IFD offset"); + return 0; + } + dirsize = 12; + } + else + { + uint64_t dircount64; + if (!ReadOK(tif, &dircount64, sizeof(uint64_t))) + { + TIFFErrorExtR(tif, module, + "%s: Can not read TIFF directory count", + tif->tif_name); + return 0; + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 4096) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed, this is " + "probably not a valid IFD offset"); + return 0; + } + dircount16 = (uint16_t)dircount64; + dirsize = 20; + } + origdir = _TIFFCheckMalloc(tif, dircount16, dirsize, + "to read TIFF directory"); + if (origdir == NULL) + return 0; + if (!ReadOK(tif, origdir, (tmsize_t)(dircount16 * dirsize))) + { + TIFFErrorExtR(tif, module, "%.100s: Can not read TIFF directory", + tif->tif_name); + _TIFFfreeExt(tif, origdir); + return 0; + } + /* + * Read offset to next directory for sequential scans if + * needed. + */ + if (nextdiroff) + { + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t nextdiroff32; + if (!ReadOK(tif, &nextdiroff32, sizeof(uint32_t))) + nextdiroff32 = 0; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdiroff32); + *nextdiroff = nextdiroff32; + } + else + { + if (!ReadOK(tif, nextdiroff, sizeof(uint64_t))) + *nextdiroff = 0; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } + } + else + { + tmsize_t m; + tmsize_t off; + if (tif->tif_diroff > (uint64_t)INT64_MAX) + { + TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); + return (0); + } + off = (tmsize_t)tif->tif_diroff; + + /* + * Check for integer overflow when validating the dir_off, + * otherwise a very high offset may cause an OOB read and + * crash the client. Make two comparisons instead of + * + * off + sizeof(uint16_t) > tif->tif_size + * + * to avoid overflow. + */ + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + m = off + sizeof(uint16_t); + if ((m < off) || (m < (tmsize_t)sizeof(uint16_t)) || + (m > tif->tif_size)) + { + TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); + return 0; + } + else + { + _TIFFmemcpy(&dircount16, tif->tif_base + off, sizeof(uint16_t)); + } + off += sizeof(uint16_t); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount16); + if (dircount16 > 4096) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed, this is " + "probably not a valid IFD offset"); + return 0; + } + dirsize = 12; + } + else + { + uint64_t dircount64; + m = off + sizeof(uint64_t); + if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) || + (m > tif->tif_size)) + { + TIFFErrorExtR(tif, module, "Can not read TIFF directory count"); + return 0; + } + else + { + _TIFFmemcpy(&dircount64, tif->tif_base + off, sizeof(uint64_t)); + } + off += sizeof(uint64_t); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 4096) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed, this is " + "probably not a valid IFD offset"); + return 0; + } + dircount16 = (uint16_t)dircount64; + dirsize = 20; + } + if (dircount16 == 0) + { + TIFFErrorExtR(tif, module, + "Sanity check on directory count failed, zero tag " + "directories not supported"); + return 0; + } + origdir = _TIFFCheckMalloc(tif, dircount16, dirsize, + "to read TIFF directory"); + if (origdir == NULL) + return 0; + m = off + dircount16 * dirsize; + if ((m < off) || (m < (tmsize_t)(dircount16 * dirsize)) || + (m > tif->tif_size)) + { + TIFFErrorExtR(tif, module, "Can not read TIFF directory"); + _TIFFfreeExt(tif, origdir); + return 0; + } + else + { + _TIFFmemcpy(origdir, tif->tif_base + off, dircount16 * dirsize); + } + if (nextdiroff) + { + off += dircount16 * dirsize; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t nextdiroff32; + m = off + sizeof(uint32_t); + if ((m < off) || (m < (tmsize_t)sizeof(uint32_t)) || + (m > tif->tif_size)) + nextdiroff32 = 0; + else + _TIFFmemcpy(&nextdiroff32, tif->tif_base + off, + sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextdiroff32); + *nextdiroff = nextdiroff32; + } + else + { + m = off + sizeof(uint64_t); + if ((m < off) || (m < (tmsize_t)sizeof(uint64_t)) || + (m > tif->tif_size)) + *nextdiroff = 0; + else + _TIFFmemcpy(nextdiroff, tif->tif_base + off, + sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(nextdiroff); + } + } + } + dir = (TIFFDirEntry *)_TIFFCheckMalloc( + tif, dircount16, sizeof(TIFFDirEntry), "to read TIFF directory"); + if (dir == 0) + { + _TIFFfreeExt(tif, origdir); + return 0; + } + ma = (uint8_t *)origdir; + mb = dir; + for (n = 0; n < dircount16; n++) + { + mb->tdir_ignore = FALSE; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + mb->tdir_tag = *(uint16_t *)ma; + ma += sizeof(uint16_t); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)ma); + mb->tdir_type = *(uint16_t *)ma; + ma += sizeof(uint16_t); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)ma); + mb->tdir_count = (uint64_t)(*(uint32_t *)ma); + ma += sizeof(uint32_t); + mb->tdir_offset.toff_long8 = 0; + *(uint32_t *)(&mb->tdir_offset) = *(uint32_t *)ma; + ma += sizeof(uint32_t); + } + else + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)ma); + mb->tdir_count = TIFFReadUInt64(ma); + ma += sizeof(uint64_t); + mb->tdir_offset.toff_long8 = TIFFReadUInt64(ma); + ma += sizeof(uint64_t); + } + mb++; + } + _TIFFfreeExt(tif, origdir); + *pdir = dir; + return dircount16; } /* * Fetch a tag that is not handled by special case code. */ -static int -TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) +static int TIFFFetchNormalTag(TIFF *tif, TIFFDirEntry *dp, int recover) { - static const char module[] = "TIFFFetchNormalTag"; - enum TIFFReadDirEntryErr err; - uint32_t fii; - const TIFFField* fip = NULL; - TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii); - if( fii == FAILED_FII ) - { - TIFFErrorExtR(tif, "TIFFFetchNormalTag", - "No definition found for tag %"PRIu16, - dp->tdir_tag); - return 0; + static const char module[] = "TIFFFetchNormalTag"; + enum TIFFReadDirEntryErr err; + uint32_t fii; + const TIFFField *fip = NULL; + TIFFReadDirectoryFindFieldInfo(tif, dp->tdir_tag, &fii); + if (fii == FAILED_FII) + { + TIFFErrorExtR(tif, "TIFFFetchNormalTag", + "No definition found for tag %" PRIu16, dp->tdir_tag); + return 0; + } + fip = tif->tif_fields[fii]; + assert(fip != NULL); /* should not happen */ + assert(fip->set_field_type != + TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with + this in specialized code */ + assert(fip->set_field_type != + TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only + the case for pseudo-tags */ + err = TIFFReadDirEntryErrOk; + switch (fip->set_field_type) + { + case TIFF_SETGET_UNDEFINED: + TIFFErrorExtR( + tif, "TIFFFetchNormalTag", + "Defined set_field_type of custom tag %u (%s) is " + "TIFF_SETGET_UNDEFINED and thus tag is not read from file", + fip->field_tag, fip->field_name); + break; + case TIFF_SETGET_ASCII: + { + uint8_t *data; + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryByteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + size_t mb = 0; + int n; + if (data != NULL) + { + if (dp->tdir_count > 0 && data[dp->tdir_count - 1] == 0) + { + /* optimization: if data is known to be 0 terminated, we + * can use strlen() */ + mb = strlen((const char *)data); + } + else + { + /* general case. equivalent to non-portable */ + /* mb = strnlen((const char*)data, + * (uint32_t)dp->tdir_count); */ + uint8_t *ma = data; + while (mb < (uint32_t)dp->tdir_count) + { + if (*ma == 0) + break; + ma++; + mb++; + } + } + } + if (mb + 1 < (uint32_t)dp->tdir_count) + TIFFWarningExtR( + tif, module, + "ASCII value for tag \"%s\" contains null byte in " + "value; value incorrectly truncated during reading due " + "to implementation limitations", + fip->field_name); + else if (mb + 1 > (uint32_t)dp->tdir_count) + { + uint8_t *o; + TIFFWarningExtR( + tif, module, + "ASCII value for tag \"%s\" does not end in null byte", + fip->field_name); + /* TIFFReadDirEntryArrayWithLimit() ensures this can't be + * larger than MAX_SIZE_TAG_DATA */ + assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1); + o = _TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1); + if (o == NULL) + { + if (data != NULL) + _TIFFfreeExt(tif, data); + return (0); + } + if (dp->tdir_count > 0) + { + _TIFFmemcpy(o, data, (uint32_t)dp->tdir_count); + } + o[(uint32_t)dp->tdir_count] = 0; + if (data != 0) + _TIFFfreeExt(tif, data); + data = o; + } + n = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!n) + return (0); + } + } + break; + case TIFF_SETGET_UINT8: + { + uint8_t data = 0; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryByte(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_SINT8: + { + int8_t data = 0; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntrySbyte(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_UINT16: + { + uint16_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryShort(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_SINT16: + { + int16_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntrySshort(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_UINT32: + { + uint32_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryLong(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_SINT32: + { + int32_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntrySlong(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_UINT64: + { + uint64_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryLong8(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_SINT64: + { + int64_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntrySlong8(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_FLOAT: + { + float data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryFloat(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_DOUBLE: + { + double data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryDouble(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_IFD8: + { + uint64_t data; + assert(fip->field_readcount == 1); + assert(fip->field_passcount == 0); + err = TIFFReadDirEntryIfd8(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + if (!TIFFSetField(tif, dp->tdir_tag, data)) + return (0); + } + } + break; + case TIFF_SETGET_UINT16_PAIR: + { + uint16_t *data; + assert(fip->field_readcount == 2); + assert(fip->field_passcount == 0); + if (dp->tdir_count != 2) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected 2, " + "got %" PRIu64, + fip->field_name, dp->tdir_count); + return (0); + } + err = TIFFReadDirEntryShortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + assert(data); /* avoid CLang static Analyzer false positive */ + m = TIFFSetField(tif, dp->tdir_tag, data[0], data[1]); + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C0_UINT8: + { + uint8_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryByteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_SINT8: + { + int8_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntrySbyteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_UINT16: + { + uint16_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryShortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_SINT16: + { + int16_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntrySshortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_UINT32: + { + uint32_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryLongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_SINT32: + { + int32_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntrySlongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_UINT64: + { + uint64_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryLong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_SINT64: + { + int64_t *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntrySlong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C0_FLOAT: + { + float *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryFloatArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read + * into Double-Arrays. */ + case TIFF_SETGET_C0_DOUBLE: + { + double *data; + assert(fip->field_readcount >= 1); + assert(fip->field_passcount == 0); + if (dp->tdir_count != (uint64_t)fip->field_readcount) + { + TIFFWarningExtR(tif, module, + "incorrect count for field \"%s\", expected " + "%d, got %" PRIu64, + fip->field_name, (int)fip->field_readcount, + dp->tdir_count); + return (0); + } + else + { + err = TIFFReadDirEntryDoubleArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_ASCII: + { + uint8_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryByteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + if (data != 0 && dp->tdir_count > 0 && + data[dp->tdir_count - 1] != '\0') + { + TIFFWarningExtR( + tif, module, + "ASCII value for tag \"%s\" does not end in null " + "byte. Forcing it to be null", + fip->field_name); + data[dp->tdir_count - 1] = '\0'; + } + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_UINT8: + { + uint8_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryByteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_SINT8: + { + int8_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntrySbyteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_UINT16: + { + uint16_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryShortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_SINT16: + { + int16_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntrySshortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_UINT32: + { + uint32_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryLongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_SINT32: + { + int32_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntrySlongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_UINT64: + { + uint64_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryLong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } } - fip=tif->tif_fields[fii]; - assert(fip != NULL); /* should not happen */ - assert(fip->set_field_type!=TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with this in specialized code */ - assert(fip->set_field_type!=TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only the case for pseudo-tags */ - err=TIFFReadDirEntryErrOk; - switch (fip->set_field_type) - { - case TIFF_SETGET_UNDEFINED: - TIFFErrorExtR(tif, "TIFFFetchNormalTag", - "Defined set_field_type of custom tag %u (%s) is TIFF_SETGET_UNDEFINED and thus tag is not read from file", - fip->field_tag, fip->field_name); - break; - case TIFF_SETGET_ASCII: - { - uint8_t* data; - assert(fip->field_passcount==0); - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - size_t mb = 0; - int n; - if (data != NULL) - { - if (dp->tdir_count > 0 && data[dp->tdir_count - 1] == 0) - { - /* optimization: if data is known to be 0 terminated, we can use strlen() */ - mb = strlen((const char*)data); - } - else - { - /* general case. equivalent to non-portable */ - /* mb = strnlen((const char*)data, (uint32_t)dp->tdir_count); */ - uint8_t* ma = data; - while (mb<(uint32_t)dp->tdir_count) - { - if (*ma==0) - break; - ma++; - mb++; - } - } - } - if (mb+1<(uint32_t)dp->tdir_count) - TIFFWarningExtR(tif,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name); - else if (mb+1>(uint32_t)dp->tdir_count) - { - uint8_t* o; - TIFFWarningExtR(tif,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name); - /* TIFFReadDirEntryArrayWithLimit() ensures this can't be larger than MAX_SIZE_TAG_DATA */ - assert((uint32_t)dp->tdir_count + 1 == dp->tdir_count + 1); - o=_TIFFmallocExt(tif, (uint32_t)dp->tdir_count + 1); - if (o==NULL) - { - if (data!=NULL) - _TIFFfreeExt(tif, data); - return(0); - } - if (dp->tdir_count > 0 ) - { - _TIFFmemcpy(o,data,(uint32_t)dp->tdir_count); - } - o[(uint32_t)dp->tdir_count]=0; - if (data!=0) - _TIFFfreeExt(tif, data); - data=o; - } - n=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!n) - return(0); - } - } - break; - case TIFF_SETGET_UINT8: - { - uint8_t data=0; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryByte(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_SINT8: - { - int8_t data = 0; - assert(fip->field_readcount == 1); - assert(fip->field_passcount == 0); - err = TIFFReadDirEntrySbyte(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif, dp->tdir_tag, data)) - return(0); - } - } - break; - case TIFF_SETGET_UINT16: - { - uint16_t data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryShort(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_SINT16: - { - int16_t data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntrySshort(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_UINT32: - { - uint32_t data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryLong(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_SINT32: - { - int32_t data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntrySlong(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_UINT64: - { - uint64_t data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryLong8(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_SINT64: - { - int64_t data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntrySlong8(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_FLOAT: - { - float data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryFloat(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_DOUBLE: - { - double data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryDouble(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_IFD8: - { - uint64_t data; - assert(fip->field_readcount==1); - assert(fip->field_passcount==0); - err=TIFFReadDirEntryIfd8(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - if (!TIFFSetField(tif,dp->tdir_tag,data)) - return(0); - } - } - break; - case TIFF_SETGET_UINT16_PAIR: - { - uint16_t* data; - assert(fip->field_readcount==2); - assert(fip->field_passcount==0); - if (dp->tdir_count!=2) { - TIFFWarningExtR(tif,module, - "incorrect count for field \"%s\", expected 2, got %"PRIu64, - fip->field_name, dp->tdir_count); - return(0); - } - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - assert(data); /* avoid CLang static Analyzer false positive */ - m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]); - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C0_UINT8: - { - uint8_t* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64_t)fip->field_readcount) { - TIFFWarningExtR(tif,module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name,(int) fip->field_readcount, dp->tdir_count); - return(0); - } - else - { - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_SINT8: - { - int8_t * data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count!=(uint64_t)fip->field_readcount) { - TIFFWarningExtR(tif, module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name, (int)fip->field_readcount, dp->tdir_count); - return(0); - } - else - { - err=TIFFReadDirEntrySbyteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_UINT16: - { - uint16_t* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) { - TIFFWarningExtR(tif, module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name, (int)fip->field_readcount, dp->tdir_count); - return(0); - } - else - { - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_SINT16: - { - int16_t* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) { - TIFFWarningExtR(tif, module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name, (int)fip->field_readcount, dp->tdir_count); - return(0); - } - else - { - err=TIFFReadDirEntrySshortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_UINT32: - { - uint32_t* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) { - TIFFWarningExtR(tif, module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name, (int)fip->field_readcount, dp->tdir_count); - return(0); - } - else - { - err=TIFFReadDirEntryLongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_SINT32: - { - int32_t* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) { - TIFFWarningExtR(tif, module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name, (int)fip->field_readcount, dp->tdir_count); - return(0); - } - else - { - err=TIFFReadDirEntrySlongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_UINT64: - { - uint64_t *data; - assert(fip->field_readcount >= 1); - assert(fip->field_passcount == 0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) { - TIFFWarningExtR(tif, module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name, (int)fip->field_readcount, dp->tdir_count); - return(0); - } else - { - err = TIFFReadDirEntryLong8Array(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_SINT64: - { - int64_t *data; - assert(fip->field_readcount >= 1); - assert(fip->field_passcount == 0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) { - TIFFWarningExtR(tif, module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name, (int)fip->field_readcount, dp->tdir_count); - return(0); - } else - { - err = TIFFReadDirEntrySlong8Array(tif, dp, &data); - if (err == TIFFReadDirEntryErrOk) - { - int m; - m = TIFFSetField(tif, dp->tdir_tag, data); - if (data != 0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C0_FLOAT: - { - float* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) { - TIFFWarningExtR(tif, module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name, (int)fip->field_readcount, dp->tdir_count); - return(0); - } - else - { - err=TIFFReadDirEntryFloatArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read into Double-Arrays. */ - case TIFF_SETGET_C0_DOUBLE: - { - double* data; - assert(fip->field_readcount>=1); - assert(fip->field_passcount==0); - if (dp->tdir_count != (uint64_t)fip->field_readcount) { - TIFFWarningExtR(tif, module, - "incorrect count for field \"%s\", expected %d, got %"PRIu64, - fip->field_name, (int)fip->field_readcount, dp->tdir_count); - return(0); - } - else - { - err=TIFFReadDirEntryDoubleArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_ASCII: - { - uint8_t* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - if( data != 0 && dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) - { - TIFFWarningExtR(tif,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); - data[dp->tdir_count-1] = '\0'; - } - m=TIFFSetField(tif, dp->tdir_tag, (uint16_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT8: - { - uint8_t* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint16_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_SINT8: - { - int8_t* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntrySbyteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT16: - { - uint16_t* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint16_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_SINT16: - { - int16_t* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntrySshortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT32: - { - uint32_t* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryLongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint16_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_SINT32: - { - int32_t* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntrySlongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_UINT64: - { - uint64_t* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryLong8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint16_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_SINT64: - { - int64_t* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntrySlong8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif,dp->tdir_tag,(uint16_t)(dp->tdir_count),data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_FLOAT: - { - float* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryFloatArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint16_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_DOUBLE: - { - double* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryDoubleArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint16_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C16_IFD8: - { - uint64_t* data; - assert(fip->field_readcount==TIFF_VARIABLE); - assert(fip->field_passcount==1); - if (dp->tdir_count>0xFFFF) - err=TIFFReadDirEntryErrCount; - else - { - err=TIFFReadDirEntryIfd8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint16_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - } - break; - case TIFF_SETGET_C32_ASCII: - { - uint8_t* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryByteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - if( data != 0 && dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) - { - TIFFWarningExtR(tif,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); - data[dp->tdir_count-1] = '\0'; - } - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT8: - { - uint8_t* data; - uint32_t count = 0; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - if( fip->field_tag == TIFFTAG_RICHTIFFIPTC && - dp->tdir_type == TIFF_LONG ) - { - /* Adobe's software (wrongly) writes RichTIFFIPTC tag with - * data type LONG instead of UNDEFINED. Work around this - * frequently found issue */ - void* origdata; - err=TIFFReadDirEntryArray(tif,dp,&count,4,&origdata); - if ((err!=TIFFReadDirEntryErrOk)||(origdata==0)) - { - data = NULL; - } - else - { - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t*)origdata,count); - data = (uint8_t*)origdata; - count = (uint32_t)(count * 4); - } - } - else - { - err=TIFFReadDirEntryByteArray(tif,dp,&data); - count = (uint32_t)(dp->tdir_count); - } - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, count, data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT8: - { - int8_t* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySbyteArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT16: - { - uint16_t* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryShortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT16: - { - int16_t* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySshortArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT32: - { - uint32_t* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryLongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT32: - { - int32_t* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySlongArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_UINT64: - { - uint64_t* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryLong8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_SINT64: - { - int64_t* data = NULL; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntrySlong8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_FLOAT: - { - float* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryFloatArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_DOUBLE: - { - double* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryDoubleArray(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - case TIFF_SETGET_C32_IFD8: - { - uint64_t* data; - assert(fip->field_readcount==TIFF_VARIABLE2); - assert(fip->field_passcount==1); - err=TIFFReadDirEntryIfd8Array(tif,dp,&data); - if (err==TIFFReadDirEntryErrOk) - { - int m; - m=TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), data); - if (data!=0) - _TIFFfreeExt(tif, data); - if (!m) - return(0); - } - } - break; - default: - assert(0); /* we should never get here */ - break; - } - if (err!=TIFFReadDirEntryErrOk) - { - TIFFReadDirEntryOutputErr(tif,err,module,fip->field_name,recover); - return(0); - } - return(1); + break; + case TIFF_SETGET_C16_SINT64: + { + int64_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntrySlong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_FLOAT: + { + float *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryFloatArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_DOUBLE: + { + double *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryDoubleArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C16_IFD8: + { + uint64_t *data; + assert(fip->field_readcount == TIFF_VARIABLE); + assert(fip->field_passcount == 1); + if (dp->tdir_count > 0xFFFF) + err = TIFFReadDirEntryErrCount; + else + { + err = TIFFReadDirEntryIfd8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, + (uint16_t)(dp->tdir_count), data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + } + break; + case TIFF_SETGET_C32_ASCII: + { + uint8_t *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryByteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + if (data != 0 && dp->tdir_count > 0 && + data[dp->tdir_count - 1] != '\0') + { + TIFFWarningExtR(tif, module, + "ASCII value for tag \"%s\" does not end " + "in null byte. Forcing it to be null", + fip->field_name); + data[dp->tdir_count - 1] = '\0'; + } + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_UINT8: + { + uint8_t *data; + uint32_t count = 0; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + if (fip->field_tag == TIFFTAG_RICHTIFFIPTC && + dp->tdir_type == TIFF_LONG) + { + /* Adobe's software (wrongly) writes RichTIFFIPTC tag with + * data type LONG instead of UNDEFINED. Work around this + * frequently found issue */ + void *origdata; + err = TIFFReadDirEntryArray(tif, dp, &count, 4, &origdata); + if ((err != TIFFReadDirEntryErrOk) || (origdata == 0)) + { + data = NULL; + } + else + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)origdata, count); + data = (uint8_t *)origdata; + count = (uint32_t)(count * 4); + } + } + else + { + err = TIFFReadDirEntryByteArray(tif, dp, &data); + count = (uint32_t)(dp->tdir_count); + } + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, count, data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_SINT8: + { + int8_t *data = NULL; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntrySbyteArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_UINT16: + { + uint16_t *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryShortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_SINT16: + { + int16_t *data = NULL; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntrySshortArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_UINT32: + { + uint32_t *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryLongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_SINT32: + { + int32_t *data = NULL; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntrySlongArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_UINT64: + { + uint64_t *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryLong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_SINT64: + { + int64_t *data = NULL; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntrySlong8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_FLOAT: + { + float *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryFloatArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_DOUBLE: + { + double *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryDoubleArray(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + case TIFF_SETGET_C32_IFD8: + { + uint64_t *data; + assert(fip->field_readcount == TIFF_VARIABLE2); + assert(fip->field_passcount == 1); + err = TIFFReadDirEntryIfd8Array(tif, dp, &data); + if (err == TIFFReadDirEntryErrOk) + { + int m; + m = TIFFSetField(tif, dp->tdir_tag, (uint32_t)(dp->tdir_count), + data); + if (data != 0) + _TIFFfreeExt(tif, data); + if (!m) + return (0); + } + } + break; + default: + assert(0); /* we should never get here */ + break; + } + if (err != TIFFReadDirEntryErrOk) + { + TIFFReadDirEntryOutputErr(tif, err, module, fip->field_name, recover); + return (0); + } + return (1); } /* * Fetch a set of offsets or lengths. * While this routine says "strips", in fact it's also used for tiles. */ -static int -TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32_t nstrips, uint64_t** lpp) +static int TIFFFetchStripThing(TIFF *tif, TIFFDirEntry *dir, uint32_t nstrips, + uint64_t **lpp) { - static const char module[] = "TIFFFetchStripThing"; - enum TIFFReadDirEntryErr err; - uint64_t* data; - err=TIFFReadDirEntryLong8ArrayWithLimit(tif,dir,&data,nstrips); - if (err!=TIFFReadDirEntryErrOk) - { - const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); - TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0); - return(0); - } - if (dir->tdir_count<(uint64_t)nstrips) - { - uint64_t* resizeddata; - const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag); - const char* pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT"); - uint32_t max_nstrips = 1000000; - if( pszMax ) - max_nstrips = (uint32_t) atoi(pszMax); - TIFFReadDirEntryOutputErr(tif,TIFFReadDirEntryErrCount, - module, - fip ? fip->field_name : "unknown tagname", - ( nstrips <= max_nstrips ) ); - - if( nstrips > max_nstrips ) - { - _TIFFfreeExt(tif, data); - return(0); - } - - resizeddata=(uint64_t*)_TIFFCheckMalloc(tif, nstrips, sizeof(uint64_t), "for strip array"); - if (resizeddata==0) { - _TIFFfreeExt(tif, data); - return(0); - } - if( dir->tdir_count ) - _TIFFmemcpy(resizeddata,data, (uint32_t)dir->tdir_count * sizeof(uint64_t)); - _TIFFmemset(resizeddata+(uint32_t)dir->tdir_count, 0, (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t)); - _TIFFfreeExt(tif, data); - data=resizeddata; - } - *lpp=data; - return(1); + static const char module[] = "TIFFFetchStripThing"; + enum TIFFReadDirEntryErr err; + uint64_t *data; + err = TIFFReadDirEntryLong8ArrayWithLimit(tif, dir, &data, nstrips); + if (err != TIFFReadDirEntryErrOk) + { + const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); + TIFFReadDirEntryOutputErr(tif, err, module, + fip ? fip->field_name : "unknown tagname", 0); + return (0); + } + if (dir->tdir_count < (uint64_t)nstrips) + { + uint64_t *resizeddata; + const TIFFField *fip = TIFFFieldWithTag(tif, dir->tdir_tag); + const char *pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT"); + uint32_t max_nstrips = 1000000; + if (pszMax) + max_nstrips = (uint32_t)atoi(pszMax); + TIFFReadDirEntryOutputErr(tif, TIFFReadDirEntryErrCount, module, + fip ? fip->field_name : "unknown tagname", + (nstrips <= max_nstrips)); + + if (nstrips > max_nstrips) + { + _TIFFfreeExt(tif, data); + return (0); + } + + resizeddata = (uint64_t *)_TIFFCheckMalloc( + tif, nstrips, sizeof(uint64_t), "for strip array"); + if (resizeddata == 0) + { + _TIFFfreeExt(tif, data); + return (0); + } + if (dir->tdir_count) + _TIFFmemcpy(resizeddata, data, + (uint32_t)dir->tdir_count * sizeof(uint64_t)); + _TIFFmemset(resizeddata + (uint32_t)dir->tdir_count, 0, + (nstrips - (uint32_t)dir->tdir_count) * sizeof(uint64_t)); + _TIFFfreeExt(tif, data); + data = resizeddata; + } + *lpp = data; + return (1); } /* * Fetch and set the SubjectDistance EXIF tag. */ -static int -TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir) +static int TIFFFetchSubjectDistance(TIFF *tif, TIFFDirEntry *dir) { - static const char module[] = "TIFFFetchSubjectDistance"; - enum TIFFReadDirEntryErr err; - UInt64Aligned_t m; - m.l=0; - assert(sizeof(double)==8); - assert(sizeof(uint64_t) == 8); - assert(sizeof(uint32_t) == 4); - if (dir->tdir_count!=1) - err=TIFFReadDirEntryErrCount; - else if (dir->tdir_type!=TIFF_RATIONAL) - err=TIFFReadDirEntryErrType; - else - { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32_t offset; - offset=*(uint32_t*)(&dir->tdir_offset); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&offset); - err=TIFFReadDirEntryData(tif,offset,8,m.i); - } - else - { - m.l=dir->tdir_offset.toff_long8; - err=TIFFReadDirEntryErrOk; - } - } - if (err==TIFFReadDirEntryErrOk) - { - double n; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(m.i,2); - if (m.i[0]==0) - n=0.0; - else if (m.i[0]==0xFFFFFFFF || m.i[1]==0) - /* - * XXX: Numerator 0xFFFFFFFF means that we have infinite - * distance. Indicate that with a negative floating point - * SubjectDistance value. - */ - n=-1.0; - else - n=(double)m.i[0]/(double)m.i[1]; - return(TIFFSetField(tif,dir->tdir_tag,n)); - } - else - { - TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE); - return(0); - } + static const char module[] = "TIFFFetchSubjectDistance"; + enum TIFFReadDirEntryErr err; + UInt64Aligned_t m; + m.l = 0; + assert(sizeof(double) == 8); + assert(sizeof(uint64_t) == 8); + assert(sizeof(uint32_t) == 4); + if (dir->tdir_count != 1) + err = TIFFReadDirEntryErrCount; + else if (dir->tdir_type != TIFF_RATIONAL) + err = TIFFReadDirEntryErrType; + else + { + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t offset; + offset = *(uint32_t *)(&dir->tdir_offset); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&offset); + err = TIFFReadDirEntryData(tif, offset, 8, m.i); + } + else + { + m.l = dir->tdir_offset.toff_long8; + err = TIFFReadDirEntryErrOk; + } + } + if (err == TIFFReadDirEntryErrOk) + { + double n; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m.i, 2); + if (m.i[0] == 0) + n = 0.0; + else if (m.i[0] == 0xFFFFFFFF || m.i[1] == 0) + /* + * XXX: Numerator 0xFFFFFFFF means that we have infinite + * distance. Indicate that with a negative floating point + * SubjectDistance value. + */ + n = -1.0; + else + n = (double)m.i[0] / (double)m.i[1]; + return (TIFFSetField(tif, dir->tdir_tag, n)); + } + else + { + TIFFReadDirEntryOutputErr(tif, err, module, "SubjectDistance", TRUE); + return (0); + } } -static void allocChoppedUpStripArrays(TIFF* tif, uint32_t nstrips, - uint64_t stripbytes, uint32_t rowsperstrip) +static void allocChoppedUpStripArrays(TIFF *tif, uint32_t nstrips, + uint64_t stripbytes, + uint32_t rowsperstrip) { TIFFDirectory *td = &tif->tif_dir; uint64_t bytecount; @@ -6568,24 +6980,26 @@ static void allocChoppedUpStripArrays(TIFF* tif, uint32_t nstrips, uint64_t *newoffsets; offset = TIFFGetStrileOffset(tif, 0); - last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1); - last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1); - if( last_offset > UINT64_MAX - last_bytecount || - last_offset + last_bytecount < offset ) + last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1); + last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips - 1); + if (last_offset > UINT64_MAX - last_bytecount || + last_offset + last_bytecount < offset) { return; } bytecount = last_offset + last_bytecount - offset; - newcounts = (uint64_t*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64_t), - "for chopped \"StripByteCounts\" array"); - newoffsets = (uint64_t*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64_t), - "for chopped \"StripOffsets\" array"); - if (newcounts == NULL || newoffsets == NULL) { + newcounts = + (uint64_t *)_TIFFCheckMalloc(tif, nstrips, sizeof(uint64_t), + "for chopped \"StripByteCounts\" array"); + newoffsets = (uint64_t *)_TIFFCheckMalloc( + tif, nstrips, sizeof(uint64_t), "for chopped \"StripOffsets\" array"); + if (newcounts == NULL || newoffsets == NULL) + { /* - * Unable to allocate new strip information, give up and use - * the original one strip information. - */ + * Unable to allocate new strip information, give up and use + * the original one strip information. + */ if (newcounts != NULL) _TIFFfreeExt(tif, newcounts); if (newoffsets != NULL) @@ -6623,77 +7037,75 @@ static void allocChoppedUpStripArrays(TIFF* tif, uint32_t nstrips, tif->tif_flags |= TIFF_CHOPPEDUPARRAYS; } - /* * Replace a single strip (tile) of uncompressed data by multiple strips * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for * dealing with large images or for dealing with machines with a limited * amount memory. */ -static void -ChopUpSingleUncompressedStrip(TIFF* tif) +static void ChopUpSingleUncompressedStrip(TIFF *tif) { - register TIFFDirectory *td = &tif->tif_dir; - uint64_t bytecount; - uint64_t offset; - uint32_t rowblock; - uint64_t rowblockbytes; - uint64_t stripbytes; - uint32_t nstrips; - uint32_t rowsperstrip; - - bytecount = TIFFGetStrileByteCount(tif, 0); - /* On a newly created file, just re-opened to be filled, we */ - /* don't want strip chop to trigger as it is going to cause issues */ - /* later ( StripOffsets and StripByteCounts improperly filled) . */ - if( bytecount == 0 && tif->tif_mode != O_RDONLY ) - return; - offset = TIFFGetStrileByteCount(tif, 0); - assert(td->td_planarconfig == PLANARCONFIG_CONTIG); - if ((td->td_photometric == PHOTOMETRIC_YCBCR)&& - (!isUpSampled(tif))) - rowblock = td->td_ycbcrsubsampling[1]; - else - rowblock = 1; - rowblockbytes = TIFFVTileSize64(tif, rowblock); - /* - * Make the rows hold at least one scanline, but fill specified amount - * of data if possible. - */ - if (rowblockbytes > STRIP_SIZE_DEFAULT) { - stripbytes = rowblockbytes; - rowsperstrip = rowblock; - } else if (rowblockbytes > 0 ) { - uint32_t rowblocksperstrip; - rowblocksperstrip = (uint32_t) (STRIP_SIZE_DEFAULT / rowblockbytes); - rowsperstrip = rowblocksperstrip * rowblock; - stripbytes = rowblocksperstrip * rowblockbytes; - } - else - return; - - /* - * never increase the number of rows per strip - */ - if (rowsperstrip >= td->td_rowsperstrip) - return; - nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); - if( nstrips == 0 ) - return; + register TIFFDirectory *td = &tif->tif_dir; + uint64_t bytecount; + uint64_t offset; + uint32_t rowblock; + uint64_t rowblockbytes; + uint64_t stripbytes; + uint32_t nstrips; + uint32_t rowsperstrip; - /* If we are going to allocate a lot of memory, make sure that the */ - /* file is as big as needed */ - if( tif->tif_mode == O_RDONLY && - nstrips > 1000000 && - (offset >= TIFFGetFileSize(tif) || - stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1)) ) - { - return; - } + bytecount = TIFFGetStrileByteCount(tif, 0); + /* On a newly created file, just re-opened to be filled, we */ + /* don't want strip chop to trigger as it is going to cause issues */ + /* later ( StripOffsets and StripByteCounts improperly filled) . */ + if (bytecount == 0 && tif->tif_mode != O_RDONLY) + return; + offset = TIFFGetStrileByteCount(tif, 0); + assert(td->td_planarconfig == PLANARCONFIG_CONTIG); + if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) + rowblock = td->td_ycbcrsubsampling[1]; + else + rowblock = 1; + rowblockbytes = TIFFVTileSize64(tif, rowblock); + /* + * Make the rows hold at least one scanline, but fill specified amount + * of data if possible. + */ + if (rowblockbytes > STRIP_SIZE_DEFAULT) + { + stripbytes = rowblockbytes; + rowsperstrip = rowblock; + } + else if (rowblockbytes > 0) + { + uint32_t rowblocksperstrip; + rowblocksperstrip = (uint32_t)(STRIP_SIZE_DEFAULT / rowblockbytes); + rowsperstrip = rowblocksperstrip * rowblock; + stripbytes = rowblocksperstrip * rowblockbytes; + } + else + return; - allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); -} + /* + * never increase the number of rows per strip + */ + if (rowsperstrip >= td->td_rowsperstrip) + return; + nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); + if (nstrips == 0) + return; + /* If we are going to allocate a lot of memory, make sure that the */ + /* file is as big as needed */ + if (tif->tif_mode == O_RDONLY && nstrips > 1000000 && + (offset >= TIFFGetFileSize(tif) || + stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1))) + { + return; + } + + allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); +} /* * Replace a file with contiguous strips > 2 GB of uncompressed data by @@ -6701,7 +7113,7 @@ ChopUpSingleUncompressedStrip(TIFF* tif) * dealing with large images or for dealing with machines with a limited * amount memory. */ -static void TryChopUpUncompressedBigTiff( TIFF* tif ) +static void TryChopUpUncompressedBigTiff(TIFF *tif) { TIFFDirectory *td = &tif->tif_dir; uint32_t rowblock; @@ -6715,48 +7127,50 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif ) stripsize = TIFFStripSize64(tif); - assert( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG ); - assert( tif->tif_dir.td_compression == COMPRESSION_NONE ); - assert( (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP ); - assert( stripsize > 0x7FFFFFFFUL ); + assert(tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG); + assert(tif->tif_dir.td_compression == COMPRESSION_NONE); + assert((tif->tif_flags & (TIFF_STRIPCHOP | TIFF_ISTILED)) == + TIFF_STRIPCHOP); + assert(stripsize > 0x7FFFFFFFUL); /* On a newly created file, just re-opened to be filled, we */ /* don't want strip chop to trigger as it is going to cause issues */ /* later ( StripOffsets and StripByteCounts improperly filled) . */ - if( TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY ) + if (TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY) return; - if ((td->td_photometric == PHOTOMETRIC_YCBCR)&& - (!isUpSampled(tif))) + if ((td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) rowblock = td->td_ycbcrsubsampling[1]; else rowblock = 1; rowblockbytes = TIFFVStripSize64(tif, rowblock); - if( rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL ) + if (rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL) { /* In case of file with gigantic width */ return; } /* Check that the strips are contiguous and of the expected size */ - for( i = 0; i < td->td_nstrips; i++ ) + for (i = 0; i < td->td_nstrips; i++) { - if( i == td->td_nstrips - 1 ) + if (i == td->td_nstrips - 1) { - if( TIFFGetStrileByteCount(tif, i) < TIFFVStripSize64( - tif, td->td_imagelength - i * td->td_rowsperstrip ) ) + if (TIFFGetStrileByteCount(tif, i) < + TIFFVStripSize64(tif, + td->td_imagelength - i * td->td_rowsperstrip)) { return; } } else { - if( TIFFGetStrileByteCount(tif, i) != stripsize ) + if (TIFFGetStrileByteCount(tif, i) != stripsize) { return; } - if( i > 0 && TIFFGetStrileOffset(tif, i) != - TIFFGetStrileOffset(tif, i-1) + TIFFGetStrileByteCount(tif, i-1) ) + if (i > 0 && TIFFGetStrileOffset(tif, i) != + TIFFGetStrileOffset(tif, i - 1) + + TIFFGetStrileByteCount(tif, i - 1)) { return; } @@ -6764,27 +7178,26 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif ) } /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */ - rowblocksperstrip = (uint32_t) (512 * 1024 * 1024 / rowblockbytes); - if( rowblocksperstrip == 0 ) + rowblocksperstrip = (uint32_t)(512 * 1024 * 1024 / rowblockbytes); + if (rowblocksperstrip == 0) rowblocksperstrip = 1; rowsperstrip = rowblocksperstrip * rowblock; stripbytes = rowblocksperstrip * rowblockbytes; - assert( stripbytes <= 0x7FFFFFFFUL ); + assert(stripbytes <= 0x7FFFFFFFUL); nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip); - if( nstrips == 0 ) + if (nstrips == 0) return; /* If we are going to allocate a lot of memory, make sure that the */ /* file is as big as needed */ - if( tif->tif_mode == O_RDONLY && - nstrips > 1000000 ) + if (tif->tif_mode == O_RDONLY && nstrips > 1000000) { uint64_t last_offset = TIFFGetStrileOffset(tif, td->td_nstrips - 1); uint64_t filesize = TIFFGetFileSize(tif); - uint64_t last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips - 1); - if( last_offset > filesize || - last_bytecount > filesize - last_offset ) + uint64_t last_bytecount = + TIFFGetStrileByteCount(tif, td->td_nstrips - 1); + if (last_offset > filesize || last_bytecount > filesize - last_offset) { return; } @@ -6793,7 +7206,6 @@ static void TryChopUpUncompressedBigTiff( TIFF* tif ) allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip); } - TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b) { @@ -6804,9 +7216,8 @@ static uint64_t _TIFFUnsanitizedAddUInt64AndInt(uint64_t a, int b) * strip/tile of number strile. Also fetch the neighbouring values using a * 4096 byte page size. */ -static -int _TIFFPartialReadStripArray(TIFF* tif, TIFFDirEntry* dirent, - int strile, uint64_t* panVals ) +static int _TIFFPartialReadStripArray(TIFF *tif, TIFFDirEntry *dirent, + int strile, uint64_t *panVals) { static const char module[] = "_TIFFPartialReadStripArray"; #define IO_CACHE_PAGE_SIZE 4096 @@ -6826,21 +7237,21 @@ int _TIFFPartialReadStripArray(TIFF* tif, TIFFDirEntry* dirent, const uint32_t arraySize = tif->tif_dir.td_stripoffsetbyteallocsize; unsigned char buffer[2 * IO_CACHE_PAGE_SIZE]; - assert( dirent->tdir_count > 4 ); + assert(dirent->tdir_count > 4); - if( dirent->tdir_type == TIFF_SHORT ) + if (dirent->tdir_type == TIFF_SHORT) { sizeofval = sizeof(uint16_t); } - else if( dirent->tdir_type == TIFF_LONG ) + else if (dirent->tdir_type == TIFF_LONG) { sizeofval = sizeof(uint32_t); } - else if( dirent->tdir_type == TIFF_LONG8 ) + else if (dirent->tdir_type == TIFF_LONG8) { sizeofval = sizeof(uint64_t); } - else if( dirent->tdir_type == TIFF_SLONG8 ) + else if (dirent->tdir_type == TIFF_SLONG8) { /* Non conformant but used by some images as in */ /* https://github.com/OSGeo/gdal/issues/2165 */ @@ -6849,54 +7260,53 @@ int _TIFFPartialReadStripArray(TIFF* tif, TIFFDirEntry* dirent, else { TIFFErrorExtR(tif, module, - "Invalid type for [Strip|Tile][Offset/ByteCount] tag"); + "Invalid type for [Strip|Tile][Offset/ByteCount] tag"); panVals[strile] = 0; return 0; } sizeofvalint = (int)(sizeofval); - if( tif->tif_flags&TIFF_BIGTIFF ) + if (tif->tif_flags & TIFF_BIGTIFF) { uint64_t offset = dirent->tdir_offset.toff_long8; - if( bSwab ) + if (bSwab) TIFFSwabLong8(&offset); nBaseOffset = offset; } else { uint32_t offset = dirent->tdir_offset.toff_long; - if( bSwab ) + if (bSwab) TIFFSwabLong(&offset); nBaseOffset = offset; } /* To avoid later unsigned integer overflows */ - if( nBaseOffset > (uint64_t)INT64_MAX ) + if (nBaseOffset > (uint64_t)INT64_MAX) { - TIFFErrorExtR(tif, module, - "Cannot read offset/size for strile %d", strile); + TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d", + strile); panVals[strile] = 0; return 0; } nOffset = nBaseOffset + sizeofval * strile; - nOffsetStartPage = - (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE; + nOffsetStartPage = (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE; nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE; - if( nOffset + sizeofval > nOffsetEndPage ) + if (nOffset + sizeofval > nOffsetEndPage) nOffsetEndPage += IO_CACHE_PAGE_SIZE; #undef IO_CACHE_PAGE_SIZE nLastStripOffset = nBaseOffset + arraySize * sizeofval; - if( nLastStripOffset < nOffsetEndPage ) + if (nLastStripOffset < nOffsetEndPage) nOffsetEndPage = nLastStripOffset; - if( nOffsetStartPage >= nOffsetEndPage ) + if (nOffsetStartPage >= nOffsetEndPage) { - TIFFErrorExtR(tif, module, - "Cannot read offset/size for strile %d", strile); + TIFFErrorExtR(tif, module, "Cannot read offset/size for strile %d", + strile); panVals[strile] = 0; return 0; } - if (!SeekOK(tif,nOffsetStartPage)) + if (!SeekOK(tif, nOffsetStartPage)) { panVals[strile] = 0; return 0; @@ -6904,47 +7314,48 @@ int _TIFFPartialReadStripArray(TIFF* tif, TIFFDirEntry* dirent, nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage); nRead = TIFFReadFile(tif, buffer, nToRead); - if( nRead < nToRead ) + if (nRead < nToRead) { TIFFErrorExtR(tif, module, - "Cannot read offset/size for strile around ~%d", strile); + "Cannot read offset/size for strile around ~%d", strile); return 0; } iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval); - if( strile + iStartBefore < 0 ) + if (strile + iStartBefore < 0) iStartBefore = -strile; - for( i = iStartBefore; + for (i = iStartBefore; (uint32_t)(strile + i) < arraySize && - _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <= nOffsetEndPage; - ++i ) + _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <= + nOffsetEndPage; + ++i) { - if( dirent->tdir_type == TIFF_SHORT ) + if (dirent->tdir_type == TIFF_SHORT) { uint16_t val; memcpy(&val, buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, sizeof(val)); - if( bSwab ) + if (bSwab) TIFFSwabShort(&val); panVals[strile + i] = val; } - else if( dirent->tdir_type == TIFF_LONG ) + else if (dirent->tdir_type == TIFF_LONG) { uint32_t val; memcpy(&val, buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, sizeof(val)); - if( bSwab ) + if (bSwab) TIFFSwabLong(&val); panVals[strile + i] = val; } - else if( dirent->tdir_type == TIFF_LONG8 ) + else if (dirent->tdir_type == TIFF_LONG8) { uint64_t val; memcpy(&val, buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, sizeof(val)); - if( bSwab ) + if (bSwab) TIFFSwabLong8(&val); panVals[strile + i] = val; } @@ -6955,97 +7366,95 @@ int _TIFFPartialReadStripArray(TIFF* tif, TIFFDirEntry* dirent, memcpy(&val, buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint, sizeof(val)); - if( bSwab ) - TIFFSwabLong8((uint64_t*) &val); - panVals[strile + i] = (uint64_t) val; + if (bSwab) + TIFFSwabLong8((uint64_t *)&val); + panVals[strile + i] = (uint64_t)val; } } return 1; } -static int _TIFFFetchStrileValue(TIFF* tif, - uint32_t strile, - TIFFDirEntry* dirent, - uint64_t** parray) +static int _TIFFFetchStrileValue(TIFF *tif, uint32_t strile, + TIFFDirEntry *dirent, uint64_t **parray) { static const char module[] = "_TIFFFetchStrileValue"; TIFFDirectory *td = &tif->tif_dir; - if( strile >= dirent->tdir_count ) + if (strile >= dirent->tdir_count) { return 0; } - if( strile >= td->td_stripoffsetbyteallocsize ) + if (strile >= td->td_stripoffsetbyteallocsize) { uint32_t nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize; uint32_t nStripArrayAllocNew; uint64_t nArraySize64; size_t nArraySize; - uint64_t* offsetArray; - uint64_t* bytecountArray; + uint64_t *offsetArray; + uint64_t *bytecountArray; - if( strile > 1000000 ) + if (strile > 1000000) { uint64_t filesize = TIFFGetFileSize(tif); /* Avoid excessive memory allocation attempt */ /* For such a big blockid we need at least a TIFF_LONG per strile */ /* for the offset array. */ - if( strile > filesize / sizeof(uint32_t) ) + if (strile > filesize / sizeof(uint32_t)) { TIFFErrorExtR(tif, module, "File too short"); return 0; } } - if( td->td_stripoffsetbyteallocsize == 0 && - td->td_nstrips < 1024 * 1024 ) + if (td->td_stripoffsetbyteallocsize == 0 && + td->td_nstrips < 1024 * 1024) { nStripArrayAllocNew = td->td_nstrips; } else { -#define TIFF_MAX(a,b) (((a)>(b)) ? (a) : (b)) -#define TIFF_MIN(a,b) (((a)<(b)) ? (a) : (b)) - nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U ); - if( nStripArrayAllocNew < 0xFFFFFFFFU / 2 ) +#define TIFF_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define TIFF_MIN(a, b) (((a) < (b)) ? (a) : (b)) + nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U); + if (nStripArrayAllocNew < 0xFFFFFFFFU / 2) nStripArrayAllocNew *= 2; nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips); } - assert( strile < nStripArrayAllocNew ); + assert(strile < nStripArrayAllocNew); nArraySize64 = (uint64_t)sizeof(uint64_t) * nStripArrayAllocNew; nArraySize = (size_t)(nArraySize64); #if SIZEOF_SIZE_T == 4 - if( nArraySize != nArraySize64 ) + if (nArraySize != nArraySize64) { TIFFErrorExtR(tif, module, - "Cannot allocate strip offset and bytecount arrays"); + "Cannot allocate strip offset and bytecount arrays"); return 0; } #endif - offsetArray = (uint64_t*)( - _TIFFreallocExt(tif, td->td_stripoffset_p, nArraySize) ); - bytecountArray = (uint64_t*)( - _TIFFreallocExt(tif, td->td_stripbytecount_p, nArraySize) ); - if( offsetArray ) + offsetArray = (uint64_t *)(_TIFFreallocExt(tif, td->td_stripoffset_p, + nArraySize)); + bytecountArray = (uint64_t *)(_TIFFreallocExt( + tif, td->td_stripbytecount_p, nArraySize)); + if (offsetArray) td->td_stripoffset_p = offsetArray; - if( bytecountArray ) + if (bytecountArray) td->td_stripbytecount_p = bytecountArray; - if( offsetArray && bytecountArray ) + if (offsetArray && bytecountArray) { td->td_stripoffsetbyteallocsize = nStripArrayAllocNew; /* Initialize new entries to ~0 / -1 */ /* coverity[overrun-buffer-arg] */ - memset(td->td_stripoffset_p + nStripArrayAllocBefore, - 0xFF, - (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * sizeof(uint64_t) ); + memset(td->td_stripoffset_p + nStripArrayAllocBefore, 0xFF, + (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * + sizeof(uint64_t)); /* coverity[overrun-buffer-arg] */ - memset(td->td_stripbytecount_p + nStripArrayAllocBefore, - 0xFF, - (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * sizeof(uint64_t) ); + memset(td->td_stripbytecount_p + nStripArrayAllocBefore, 0xFF, + (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * + sizeof(uint64_t)); } else { TIFFErrorExtR(tif, module, - "Cannot allocate strip offset and bytecount arrays"); + "Cannot allocate strip offset and bytecount arrays"); _TIFFfreeExt(tif, td->td_stripoffset_p); td->td_stripoffset_p = NULL; _TIFFfreeExt(tif, td->td_stripbytecount_p); @@ -7053,12 +7462,12 @@ static int _TIFFFetchStrileValue(TIFF* tif, td->td_stripoffsetbyteallocsize = 0; } } - if( *parray == NULL || strile >= td->td_stripoffsetbyteallocsize ) + if (*parray == NULL || strile >= td->td_stripoffsetbyteallocsize) return 0; - if( ~((*parray)[strile]) == 0 ) + if (~((*parray)[strile]) == 0) { - if( !_TIFFPartialReadStripArray( tif, dirent, strile, *parray ) ) + if (!_TIFFPartialReadStripArray(tif, dirent, strile, *parray)) { (*parray)[strile] = 0; return 0; @@ -7069,23 +7478,24 @@ static int _TIFFFetchStrileValue(TIFF* tif, } static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile, - TIFFDirEntry* dirent, - uint64_t** parray, + TIFFDirEntry *dirent, + uint64_t **parray, int *pbErr) { TIFFDirectory *td = &tif->tif_dir; - if( pbErr ) + if (pbErr) *pbErr = 0; - if( (tif->tif_flags&TIFF_DEFERSTRILELOAD) && !(tif->tif_flags&TIFF_CHOPPEDUPARRAYS) ) + if ((tif->tif_flags & TIFF_DEFERSTRILELOAD) && + !(tif->tif_flags & TIFF_CHOPPEDUPARRAYS)) { - if( !(tif->tif_flags&TIFF_LAZYSTRILELOAD) || + if (!(tif->tif_flags & TIFF_LAZYSTRILELOAD) || /* If the values may fit in the toff_long/toff_long8 member */ /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */ - dirent->tdir_count <= 4 ) + dirent->tdir_count <= 4) { - if( !_TIFFFillStriles(tif) ) + if (!_TIFFFillStriles(tif)) { - if( pbErr ) + if (pbErr) *pbErr = 1; /* Do not return, as we want this function to always */ /* return the same value if called several times with */ @@ -7094,69 +7504,70 @@ static uint64_t _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32_t strile, } else { - if( !_TIFFFetchStrileValue(tif, strile, dirent, parray) ) - { - if( pbErr ) + if (!_TIFFFetchStrileValue(tif, strile, dirent, parray)) + { + if (pbErr) *pbErr = 1; - return 0; - } + return 0; + } } } - if( *parray == NULL || strile >= td->td_nstrips ) + if (*parray == NULL || strile >= td->td_nstrips) { - if( pbErr ) + if (pbErr) *pbErr = 1; return 0; } return (*parray)[strile]; } -/* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile */ +/* Return the value of the TileOffsets/StripOffsets array for the specified + * tile/strile */ uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile) { return TIFFGetStrileOffsetWithErr(tif, strile, NULL); } -/* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile */ +/* Return the value of the TileOffsets/StripOffsets array for the specified + * tile/strile */ uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, int *pbErr) { TIFFDirectory *td = &tif->tif_dir; return _TIFFGetStrileOffsetOrByteCountValue(tif, strile, - &(td->td_stripoffset_entry), - &(td->td_stripoffset_p), pbErr); + &(td->td_stripoffset_entry), + &(td->td_stripoffset_p), pbErr); } -/* Return the value of the TileByteCounts/StripByteCounts array for the specified tile/strile */ +/* Return the value of the TileByteCounts/StripByteCounts array for the + * specified tile/strile */ uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile) { return TIFFGetStrileByteCountWithErr(tif, strile, NULL); } -/* Return the value of the TileByteCounts/StripByteCounts array for the specified tile/strile */ +/* Return the value of the TileByteCounts/StripByteCounts array for the + * specified tile/strile */ uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, int *pbErr) { TIFFDirectory *td = &tif->tif_dir; - return _TIFFGetStrileOffsetOrByteCountValue(tif, strile, - &(td->td_stripbytecount_entry), - &(td->td_stripbytecount_p), pbErr); + return _TIFFGetStrileOffsetOrByteCountValue( + tif, strile, &(td->td_stripbytecount_entry), &(td->td_stripbytecount_p), + pbErr); } +int _TIFFFillStriles(TIFF *tif) { return _TIFFFillStrilesInternal(tif, 1); } -int _TIFFFillStriles( TIFF *tif ) -{ - return _TIFFFillStrilesInternal( tif, 1 ); -} - -static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount ) +static int _TIFFFillStrilesInternal(TIFF *tif, int loadStripByteCount) { register TIFFDirectory *td = &tif->tif_dir; int return_value = 1; /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */ - if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) || (tif->tif_flags&TIFF_CHOPPEDUPARRAYS) != 0 ) + if (!(tif->tif_flags & TIFF_DEFERSTRILELOAD) || + (tif->tif_flags & TIFF_CHOPPEDUPARRAYS) != 0) return 1; - if( tif->tif_flags&TIFF_LAZYSTRILELOAD ) + if (tif->tif_flags & TIFF_LAZYSTRILELOAD) { /* In case of lazy loading, reload completely the arrays */ _TIFFfreeExt(tif, td->td_stripoffset_p); @@ -7168,41 +7579,44 @@ static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount ) } /* If stripoffset array is already loaded, exit with success */ - if( td->td_stripoffset_p != NULL ) - return 1; + if (td->td_stripoffset_p != NULL) + return 1; /* If tdir_count was canceled, then we already got there, but in error */ - if( td->td_stripoffset_entry.tdir_count == 0 ) - return 0; + if (td->td_stripoffset_entry.tdir_count == 0) + return 0; - if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry), - td->td_nstrips,&td->td_stripoffset_p)) + if (!TIFFFetchStripThing(tif, &(td->td_stripoffset_entry), td->td_nstrips, + &td->td_stripoffset_p)) { - return_value = 0; + return_value = 0; } if (loadStripByteCount && - !TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry), - td->td_nstrips,&td->td_stripbytecount_p)) + !TIFFFetchStripThing(tif, &(td->td_stripbytecount_entry), + td->td_nstrips, &td->td_stripbytecount_p)) { - return_value = 0; + return_value = 0; } - _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); - _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); + _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); #ifdef STRIPBYTECOUNTSORTED_UNUSED - if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) { - uint32_t strip; - - tif->tif_dir.td_stripbytecountsorted = 1; - for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) { - if (tif->tif_dir.td_stripoffset_p[strip - 1] > - tif->tif_dir.td_stripoffset_p[strip]) { - tif->tif_dir.td_stripbytecountsorted = 0; - break; - } + if (tif->tif_dir.td_nstrips > 1 && return_value == 1) + { + uint32_t strip; + + tif->tif_dir.td_stripbytecountsorted = 1; + for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) + { + if (tif->tif_dir.td_stripoffset_p[strip - 1] > + tif->tif_dir.td_stripoffset_p[strip]) + { + tif->tif_dir.td_stripbytecountsorted = 0; + break; } + } } #endif diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c index ca052804..beebd116 100644 --- a/libtiff/tif_dirwrite.c +++ b/libtiff/tif_dirwrite.c @@ -28,79 +28,203 @@ * Directory Write Support Routines. */ #include "tiffiop.h" -#include <float.h> /*--: for Rational2Double */ -#include <math.h> /*--: for Rational2Double */ +#include <float.h> /*--: for Rational2Double */ +#include <math.h> /*--: for Rational2Double */ #ifdef HAVE_IEEEFP #define TIFFCvtNativeToIEEEFloat(tif, n, fp) #define TIFFCvtNativeToIEEEDouble(tif, n, dp) #else -extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32_t n, float* fp); -extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32_t n, double* dp); +extern void TIFFCvtNativeToIEEEFloat(TIFF *tif, uint32_t n, float *fp); +extern void TIFFCvtNativeToIEEEDouble(TIFF *tif, uint32_t n, double *dp); #endif -static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff); - -static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value); - -static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, char* value); -static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value); -static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value); -static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int8_t* value); -static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value); -static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint16_t* value); -static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value); -static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int16_t* value); -static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value); -static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value); -static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int32_t* value); -static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value); -static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int64_t* value); -static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value); -static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value); -static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value); -static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value); -static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value); -static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value); -static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value); -static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value); -static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value); -static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir); -static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir); -static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir); - -static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, char* value); -static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value); -static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value); -static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int8_t* value); -static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value); -static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint16_t* value); -static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int16_t* value); -static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value); -static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value); -static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int32_t* value); -static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value); -static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int64_t* value); -static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value); -static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value); -static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value); - -/*--: Rational2Double: New functions to support true double-precision for custom rational tag types. */ -static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value); -static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value); -static int TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value); -static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value); +static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, + uint64_t *pdiroff); + +static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + double *value); + +static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, char *value); +static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint8_t *value); +static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint8_t *value); +static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int8_t *value); +static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value); +static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint16_t *value); +static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value); +static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int16_t *value); +static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value); +static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint32_t *value); +static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int32_t *value); +static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value); +static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int64_t *value); +static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + double value); +static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value); +static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value); +static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value); +static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, double *value); +static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint32_t *value); +static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value); +static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value); +static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value); +static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir); +static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir); +static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir); + +static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, char *value); +static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + uint8_t *value); +static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint8_t *value); +static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int8_t *value); +static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value); +static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint16_t *value); +static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int16_t *value); +static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value); +static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint32_t *value); +static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int32_t *value); +static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint64_t *value); +static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int64_t *value); +static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + double value); +static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + float *value); +static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + float *value); + +/*--: Rational2Double: New functions to support true double-precision for custom + * rational tag types. */ +static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + double *value); +static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + double *value); +static int +TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, double *value); +static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray( + TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count, + double *value); static void DoubleToRational(double value, uint32_t *num, uint32_t *denom); static void DoubleToSrational(double value, int32_t *num, int32_t *denom); -static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value); -static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value); -static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value); -static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value); - -static int TIFFWriteDirectoryTagData(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t datatype, uint32_t count, uint32_t datalength, void* data); - -static int TIFFLinkDirectory(TIFF*); +static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + float *value); +static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + double *value); +static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, + uint32_t *value); +static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint64_t *value); + +static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t datatype, uint32_t count, + uint32_t datalength, void *data); + +static int TIFFLinkDirectory(TIFF *); /* * Write the contents of the current directory @@ -108,10 +232,9 @@ static int TIFFLinkDirectory(TIFF*); * handle overwriting a directory with auxiliary * storage that's been changed. */ -int -TIFFWriteDirectory(TIFF* tif) +int TIFFWriteDirectory(TIFF *tif) { - return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL); + return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL); } /* @@ -139,19 +262,17 @@ TIFFWriteDirectory(TIFF* tif) * * Returns 1 in case of success, 0 otherwise. */ -int TIFFDeferStrileArrayWriting(TIFF* tif) +int TIFFDeferStrileArrayWriting(TIFF *tif) { static const char module[] = "TIFFDeferStrileArrayWriting"; if (tif->tif_mode == O_RDONLY) { - TIFFErrorExtR(tif, tif->tif_name, - "File opened in read-only mode"); + TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode"); return 0; } - if( tif->tif_diroff != 0 ) + if (tif->tif_diroff != 0) { - TIFFErrorExtR(tif, module, - "Directory has already been written"); + TIFFErrorExtR(tif, module, "Directory has already been written"); return 0; } @@ -165,375 +286,425 @@ int TIFFDeferStrileArrayWriting(TIFF* tif) * written again. This will make a partially written TIFF file * readable before it is successfully completed/closed. */ -int -TIFFCheckpointDirectory(TIFF* tif) +int TIFFCheckpointDirectory(TIFF *tif) { - int rc; - /* Setup the strips arrays, if they haven't already been. */ - if (tif->tif_dir.td_stripoffset_p == NULL) - (void) TIFFSetupStrips(tif); - rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL); - (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END)); - return rc; + int rc; + /* Setup the strips arrays, if they haven't already been. */ + if (tif->tif_dir.td_stripoffset_p == NULL) + (void)TIFFSetupStrips(tif); + rc = TIFFWriteDirectorySec(tif, TRUE, FALSE, NULL); + (void)TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END)); + return rc; } -int -TIFFWriteCustomDirectory(TIFF* tif, uint64_t* pdiroff) +int TIFFWriteCustomDirectory(TIFF *tif, uint64_t *pdiroff) { - return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff); + return TIFFWriteDirectorySec(tif, FALSE, FALSE, pdiroff); } /* * Similar to TIFFWriteDirectory(), but if the directory has already * been written once, it is relocated to the end of the file, in case it * has changed in size. Note that this will result in the loss of the - * previously used directory space. - */ -int -TIFFRewriteDirectory( TIFF *tif ) -{ - static const char module[] = "TIFFRewriteDirectory"; - - /* We don't need to do anything special if it hasn't been written. */ - if( tif->tif_diroff == 0 ) - return TIFFWriteDirectory( tif ); - - /* - * Find and zero the pointer to this directory, so that TIFFLinkDirectory - * will cause it to be added after this directories current pre-link. - */ - - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff) - { - tif->tif_header.classic.tiff_diroff = 0; - tif->tif_diroff = 0; - - TIFFSeekFile(tif,4,SEEK_SET); - if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4)) - { - TIFFErrorExtR(tif, tif->tif_name, - "Error updating TIFF header"); - return (0); - } - } - else if( tif->tif_diroff > 0xFFFFFFFFU ) - { - TIFFErrorExtR(tif, module, - "tif->tif_diroff exceeds 32 bit range allowed for Classic TIFF"); - return (0); - } - else - { - uint32_t nextdir; - nextdir = tif->tif_header.classic.tiff_diroff; - while(1) { - uint16_t dircount; - uint32_t nextnextdir; - - if (!SeekOK(tif, nextdir) || - !ReadOK(tif, &dircount, 2)) { - TIFFErrorExtR(tif, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - (void) TIFFSeekFile(tif, - nextdir+2+dircount*12, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 4)) { - TIFFErrorExtR(tif, module, - "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextnextdir); - if (nextnextdir==tif->tif_diroff) - { - uint32_t m; - m=0; - (void) TIFFSeekFile(tif, - nextdir+2+dircount*12, SEEK_SET); - if (!WriteOK(tif, &m, 4)) { - TIFFErrorExtR(tif, module, - "Error writing directory link"); - return (0); - } - tif->tif_diroff=0; - /* Force a full-traversal to reach the zeroed pointer */ - tif->tif_lastdiroff=0; - break; - } - nextdir=nextnextdir; - } - } - } - else - { - if (tif->tif_header.big.tiff_diroff == tif->tif_diroff) - { - tif->tif_header.big.tiff_diroff = 0; - tif->tif_diroff = 0; - - TIFFSeekFile(tif,8,SEEK_SET); - if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8)) - { - TIFFErrorExtR(tif, tif->tif_name, - "Error updating TIFF header"); - return (0); - } - } - else - { - uint64_t nextdir; - nextdir = tif->tif_header.big.tiff_diroff; - while(1) { - uint64_t dircount64; - uint16_t dircount; - uint64_t nextnextdir; - - if (!SeekOK(tif, nextdir) || - !ReadOK(tif, &dircount64, 8)) { - TIFFErrorExtR(tif, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>0xFFFF) - { - TIFFErrorExtR(tif, module, - "Sanity check on tag count failed, likely corrupt TIFF"); - return (0); - } - dircount=(uint16_t)dircount64; - (void) TIFFSeekFile(tif, - nextdir+8+dircount*20, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 8)) { - TIFFErrorExtR(tif, module, - "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&nextnextdir); - if (nextnextdir==tif->tif_diroff) - { - uint64_t m; - m=0; - (void) TIFFSeekFile(tif, - nextdir+8+dircount*20, SEEK_SET); - if (!WriteOK(tif, &m, 8)) { - TIFFErrorExtR(tif, module, - "Error writing directory link"); - return (0); - } - tif->tif_diroff=0; - /* Force a full-traversal to reach the zeroed pointer */ - tif->tif_lastdiroff=0; - break; - } - nextdir=nextnextdir; - } - } - } - - /* - * Now use TIFFWriteDirectory() normally. - */ - - return TIFFWriteDirectory( tif ); -} + * previously used directory space. + */ +int TIFFRewriteDirectory(TIFF *tif) +{ + static const char module[] = "TIFFRewriteDirectory"; -static int -TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff) -{ - static const char module[] = "TIFFWriteDirectorySec"; - uint32_t ndir; - TIFFDirEntry* dir; - uint32_t dirsize; - void* dirmem; - uint32_t m; - if (tif->tif_mode == O_RDONLY) - return (1); - - _TIFFFillStriles( tif ); - - /* - * Clear write state so that subsequent images with - * different characteristics get the right buffers - * setup for them. - */ - if (imagedone) - { - if (tif->tif_flags & TIFF_POSTENCODE) - { - tif->tif_flags &= ~TIFF_POSTENCODE; - if (!(*tif->tif_postencode)(tif)) - { - TIFFErrorExtR(tif,module, - "Error post-encoding before directory write"); - return (0); - } - } - (*tif->tif_close)(tif); /* shutdown encoder */ - /* - * Flush any data that might have been written - * by the compression close+cleanup routines. But - * be careful not to write stuff if we didn't add data - * in the previous steps as the "rawcc" data may well be - * a previously read tile/strip in mixed read/write mode. - */ - if (tif->tif_rawcc > 0 - && (tif->tif_flags & TIFF_BEENWRITING) != 0 ) - { - if( !TIFFFlushData1(tif) ) + /* We don't need to do anything special if it hasn't been written. */ + if (tif->tif_diroff == 0) + return TIFFWriteDirectory(tif); + + /* + * Find and zero the pointer to this directory, so that TIFFLinkDirectory + * will cause it to be added after this directories current pre-link. + */ + + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff) + { + tif->tif_header.classic.tiff_diroff = 0; + tif->tif_diroff = 0; + + TIFFSeekFile(tif, 4, SEEK_SET); + if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4)) + { + TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header"); + return (0); + } + } + else if (tif->tif_diroff > 0xFFFFFFFFU) + { + TIFFErrorExtR(tif, module, + "tif->tif_diroff exceeds 32 bit range allowed for " + "Classic TIFF"); + return (0); + } + else + { + uint32_t nextdir; + nextdir = tif->tif_header.classic.tiff_diroff; + while (1) + { + uint16_t dircount; + uint32_t nextnextdir; + + if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2)) + { + TIFFErrorExtR(tif, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 4)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextnextdir); + if (nextnextdir == tif->tif_diroff) + { + uint32_t m; + m = 0; + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, + SEEK_SET); + if (!WriteOK(tif, &m, 4)) { - TIFFErrorExtR(tif, module, - "Error flushing data before directory write"); - return (0); + TIFFErrorExtR(tif, module, + "Error writing directory link"); + return (0); } - } - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) - { - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawcc = 0; - tif->tif_rawdatasize = 0; - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = 0; - } - tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP); - } - - if (TIFFFieldSet(tif,FIELD_COMPRESSION) && (tif->tif_dir.td_compression == COMPRESSION_DEFLATE)) { - TIFFWarningExtR(tif, module, - "Creating TIFF with legacy Deflate codec identifier, " - "COMPRESSION_ADOBE_DEFLATE is more widely supported"); - } - dir=NULL; - dirmem=NULL; - dirsize=0; - while (1) - { - ndir=0; - if (isimage) - { - if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) - { - if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth)) - goto bad; - if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) - { - if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth)) - goto bad; - if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_RESOLUTION)) - { - if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution)) - goto bad; - if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_POSITION)) - { - if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition)) - goto bad; - if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) - { - if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) - { - if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_COMPRESSION)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_FILLORDER)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_ORIENTATION)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) - { - if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_PAGENUMBER)) - { - if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0])) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS)) - { - if (!isTiled(tif)) - { - if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p)) - goto bad; - } - else - { - if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p)) - goto bad; - } - } - if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) - { - if (!isTiled(tif)) - { + tif->tif_diroff = 0; + /* Force a full-traversal to reach the zeroed pointer */ + tif->tif_lastdiroff = 0; + break; + } + nextdir = nextnextdir; + } + } + } + else + { + if (tif->tif_header.big.tiff_diroff == tif->tif_diroff) + { + tif->tif_header.big.tiff_diroff = 0; + tif->tif_diroff = 0; + + TIFFSeekFile(tif, 8, SEEK_SET); + if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff), 8)) + { + TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header"); + return (0); + } + } + else + { + uint64_t nextdir; + nextdir = tif->tif_header.big.tiff_diroff; + while (1) + { + uint64_t dircount64; + uint16_t dircount; + uint64_t nextnextdir; + + if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8)) + { + TIFFErrorExtR(tif, module, + "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 0xFFFF) + { + TIFFErrorExtR(tif, module, + "Sanity check on tag count failed, likely " + "corrupt TIFF"); + return (0); + } + dircount = (uint16_t)dircount64; + (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 8)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextnextdir); + if (nextnextdir == tif->tif_diroff) + { + uint64_t m; + m = 0; + (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, + SEEK_SET); + if (!WriteOK(tif, &m, 8)) + { + TIFFErrorExtR(tif, module, + "Error writing directory link"); + return (0); + } + tif->tif_diroff = 0; + /* Force a full-traversal to reach the zeroed pointer */ + tif->tif_lastdiroff = 0; + break; + } + nextdir = nextnextdir; + } + } + } + + /* + * Now use TIFFWriteDirectory() normally. + */ + + return TIFFWriteDirectory(tif); +} + +static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone, + uint64_t *pdiroff) +{ + static const char module[] = "TIFFWriteDirectorySec"; + uint32_t ndir; + TIFFDirEntry *dir; + uint32_t dirsize; + void *dirmem; + uint32_t m; + if (tif->tif_mode == O_RDONLY) + return (1); + + _TIFFFillStriles(tif); + + /* + * Clear write state so that subsequent images with + * different characteristics get the right buffers + * setup for them. + */ + if (imagedone) + { + if (tif->tif_flags & TIFF_POSTENCODE) + { + tif->tif_flags &= ~TIFF_POSTENCODE; + if (!(*tif->tif_postencode)(tif)) + { + TIFFErrorExtR(tif, module, + "Error post-encoding before directory write"); + return (0); + } + } + (*tif->tif_close)(tif); /* shutdown encoder */ + /* + * Flush any data that might have been written + * by the compression close+cleanup routines. But + * be careful not to write stuff if we didn't add data + * in the previous steps as the "rawcc" data may well be + * a previously read tile/strip in mixed read/write mode. + */ + if (tif->tif_rawcc > 0 && (tif->tif_flags & TIFF_BEENWRITING) != 0) + { + if (!TIFFFlushData1(tif)) + { + TIFFErrorExtR(tif, module, + "Error flushing data before directory write"); + return (0); + } + } + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + { + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawcc = 0; + tif->tif_rawdatasize = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; + } + tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP); + } + + if (TIFFFieldSet(tif, FIELD_COMPRESSION) && + (tif->tif_dir.td_compression == COMPRESSION_DEFLATE)) + { + TIFFWarningExtR(tif, module, + "Creating TIFF with legacy Deflate codec identifier, " + "COMPRESSION_ADOBE_DEFLATE is more widely supported"); + } + dir = NULL; + dirmem = NULL; + dirsize = 0; + while (1) + { + ndir = 0; + if (isimage) + { + if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) + { + if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir, + TIFFTAG_IMAGEWIDTH, + tif->tif_dir.td_imagewidth)) + goto bad; + if (!TIFFWriteDirectoryTagShortLong( + tif, &ndir, dir, TIFFTAG_IMAGELENGTH, + tif->tif_dir.td_imagelength)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) + { + if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir, + TIFFTAG_TILEWIDTH, + tif->tif_dir.td_tilewidth)) + goto bad; + if (!TIFFWriteDirectoryTagShortLong(tif, &ndir, dir, + TIFFTAG_TILELENGTH, + tif->tif_dir.td_tilelength)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_RESOLUTION)) + { + if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, + TIFFTAG_XRESOLUTION, + tif->tif_dir.td_xresolution)) + goto bad; + if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, + TIFFTAG_YRESOLUTION, + tif->tif_dir.td_yresolution)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_POSITION)) + { + if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, + TIFFTAG_XPOSITION, + tif->tif_dir.td_xposition)) + goto bad; + if (!TIFFWriteDirectoryTagRational(tif, &ndir, dir, + TIFFTAG_YPOSITION, + tif->tif_dir.td_yposition)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_SUBFILETYPE)) + { + if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, + TIFFTAG_SUBFILETYPE, + tif->tif_dir.td_subfiletype)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) + { + if (!TIFFWriteDirectoryTagShortPerSample( + tif, &ndir, dir, TIFFTAG_BITSPERSAMPLE, + tif->tif_dir.td_bitspersample)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_COMPRESSION)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_COMPRESSION, + tif->tif_dir.td_compression)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_PHOTOMETRIC, + tif->tif_dir.td_photometric)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_THRESHHOLDING)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_THRESHHOLDING, + tif->tif_dir.td_threshholding)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_FILLORDER)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_FILLORDER, + tif->tif_dir.td_fillorder)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_ORIENTATION)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_ORIENTATION, + tif->tif_dir.td_orientation)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) + { + if (!TIFFWriteDirectoryTagShort( + tif, &ndir, dir, TIFFTAG_SAMPLESPERPIXEL, + tif->tif_dir.td_samplesperpixel)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) + { + if (!TIFFWriteDirectoryTagShortLong( + tif, &ndir, dir, TIFFTAG_ROWSPERSTRIP, + tif->tif_dir.td_rowsperstrip)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagShortPerSample( + tif, &ndir, dir, TIFFTAG_MINSAMPLEVALUE, + tif->tif_dir.td_minsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagShortPerSample( + tif, &ndir, dir, TIFFTAG_MAXSAMPLEVALUE, + tif->tif_dir.td_maxsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_PLANARCONFIG)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_PLANARCONFIG, + tif->tif_dir.td_planarconfig)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_RESOLUTIONUNIT, + tif->tif_dir.td_resolutionunit)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_PAGENUMBER)) + { + if (!TIFFWriteDirectoryTagShortArray( + tif, &ndir, dir, TIFFTAG_PAGENUMBER, 2, + &tif->tif_dir.td_pagenumber[0])) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) + { + if (!isTiled(tif)) + { + if (!TIFFWriteDirectoryTagLongLong8Array( + tif, &ndir, dir, TIFFTAG_STRIPBYTECOUNTS, + tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripbytecount_p)) + goto bad; + } + else + { + if (!TIFFWriteDirectoryTagLongLong8Array( + tif, &ndir, dir, TIFFTAG_TILEBYTECOUNTS, + tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripbytecount_p)) + goto bad; + } + } + if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) + { + if (!isTiled(tif)) + { /* td_stripoffset_p might be NULL in an odd OJPEG case. See * tif_dirread.c around line 3634. * XXX: OJPEG hack. @@ -544,700 +715,832 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff) * JpegInterchangeFormat stream. * We can get here when using tiffset on such a file. * See http://bugzilla.maptools.org/show_bug.cgi?id=2500 - */ + */ if (tif->tif_dir.td_stripoffset_p != NULL && - !TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p)) + !TIFFWriteDirectoryTagLongLong8Array( + tif, &ndir, dir, TIFFTAG_STRIPOFFSETS, + tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripoffset_p)) goto bad; - } - else - { - if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p)) - goto bad; - } - } - if (TIFFFieldSet(tif,FIELD_COLORMAP)) - { - if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES)) - { - if (tif->tif_dir.td_extrasamples) - { - uint16_t na; - uint16_t* nb; - TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb); - if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb)) - goto bad; - } - } - if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) - { - if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) - { - if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH)) - { - if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_TILEDEPTH)) - { - if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS)) - { - if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0])) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING)) - { - if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0])) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) - { - if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) - { - if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) - { - if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_INKNAMES)) - { - if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames)) - goto bad; - } - if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) - { - if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, TIFFTAG_NUMBEROFINKS, tif->tif_dir.td_numberofinks)) - goto bad; - } - if (TIFFFieldSet(tif,FIELD_SUBIFD)) - { - if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir)) - goto bad; - } - { - uint32_t n; - for (n=0; n<tif->tif_nfields; n++) { - const TIFFField* o; - o = tif->tif_fields[n]; - if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit))) - { - switch (o->get_field_type) - { - case TIFF_SETGET_ASCII: - { - uint32_t pa; - char* pb; - assert(o->field_type==TIFF_ASCII); - assert(o->field_readcount==TIFF_VARIABLE); - assert(o->field_passcount==0); - TIFFGetField(tif,o->field_tag,&pb); - pa=(uint32_t)(strlen(pb)); - if (!TIFFWriteDirectoryTagAscii(tif, &ndir, dir, (uint16_t)o->field_tag, pa, pb)) - goto bad; - } - break; - case TIFF_SETGET_UINT16: - { - uint16_t p; - assert(o->field_type==TIFF_SHORT); - assert(o->field_readcount==1); - assert(o->field_passcount==0); - TIFFGetField(tif,o->field_tag,&p); - if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, (uint16_t)o->field_tag, p)) - goto bad; - } - break; - case TIFF_SETGET_UINT32: - { - uint32_t p; - assert(o->field_type==TIFF_LONG); - assert(o->field_readcount==1); - assert(o->field_passcount==0); - TIFFGetField(tif,o->field_tag,&p); - if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, (uint16_t)o->field_tag, p)) - goto bad; - } - break; - case TIFF_SETGET_C32_UINT8: - { - uint32_t pa; - void* pb; - assert(o->field_type==TIFF_UNDEFINED); - assert(o->field_readcount==TIFF_VARIABLE2); - assert(o->field_passcount==1); - TIFFGetField(tif,o->field_tag,&pa,&pb); - if (!TIFFWriteDirectoryTagUndefinedArray(tif, &ndir, dir, (uint16_t)o->field_tag, pa, pb)) - goto bad; - } - break; - default: - TIFFErrorExtR(tif,module, - "Cannot write tag %"PRIu32" (%s)", - TIFFFieldTag(o), - o->field_name ? o->field_name : "unknown"); - goto bad; - } - } - } - } - } - for (m=0; m<(uint32_t)(tif->tif_dir.td_customValueCount); m++) - { - uint16_t tag = (uint16_t)tif->tif_dir.td_customValues[m].info->field_tag; - uint32_t count = tif->tif_dir.td_customValues[m].count; - switch (tif->tif_dir.td_customValues[m].info->field_type) - { - case TIFF_ASCII: - if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_UNDEFINED: - if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_BYTE: - if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_SBYTE: - if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_SHORT: - if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_SSHORT: - if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_LONG: - if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_SLONG: - if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_LONG8: - if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_SLONG8: - if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_RATIONAL: - { - /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ - int tv_size; - tv_size = TIFFFieldSetGetSize(tif->tif_dir.td_customValues[m].info); - if (tv_size == 8) { - if (!TIFFWriteDirectoryTagRationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - } else { - /*-- default should be tv_size == 4 */ - if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */ - if (tv_size != 4) { - TIFFErrorExtR(tif,"TIFFLib: _TIFFWriteDirectorySec()", "Rational2Double: .set_field_type is not 4 but %d", tv_size); - } - } - } - break; - case TIFF_SRATIONAL: - { - /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ - int tv_size; - tv_size = TIFFFieldSetGetSize(tif->tif_dir.td_customValues[m].info); - if (tv_size == 8) { - if (!TIFFWriteDirectoryTagSrationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - } else { - /*-- default should be tv_size == 4 */ - if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */ - if (tv_size != 4) { - TIFFErrorExtR(tif,"TIFFLib: _TIFFWriteDirectorySec()", "Rational2Double: .set_field_type is not 4 but %d", tv_size); - } - } - } - break; - case TIFF_FLOAT: - if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_DOUBLE: - if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_IFD: - if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - case TIFF_IFD8: - if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value)) - goto bad; - break; - default: - assert(0); /* we should never get here */ - break; - } - } - if (dir!=NULL) - break; - dir=_TIFFmallocExt(tif, ndir*sizeof(TIFFDirEntry)); - if (dir==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - goto bad; - } - if (isimage) - { - if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif))) - goto bad; - } - else - tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~((toff_t)1)); - if (pdiroff!=NULL) - *pdiroff=tif->tif_diroff; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - dirsize=2+ndir*12+4; - else - dirsize=8+ndir*20+8; - tif->tif_dataoff=tif->tif_diroff+dirsize; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - tif->tif_dataoff=(uint32_t)tif->tif_dataoff; - if ((tif->tif_dataoff<tif->tif_diroff)||(tif->tif_dataoff<(uint64_t)dirsize)) - { - TIFFErrorExtR(tif,module,"Maximum TIFF file size exceeded"); - goto bad; - } - if (tif->tif_dataoff&1) - tif->tif_dataoff++; - if (isimage) - tif->tif_curdir++; - } - if (isimage) - { - if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0)) - { - uint32_t na; - TIFFDirEntry* nb; - for (na=0, nb=dir; ; na++, nb++) - { - if( na == ndir ) - { - TIFFErrorExtR(tif,module, - "Cannot find SubIFD tag"); + } + else + { + if (!TIFFWriteDirectoryTagLongLong8Array( + tif, &ndir, dir, TIFFTAG_TILEOFFSETS, + tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripoffset_p)) + goto bad; + } + } + if (TIFFFieldSet(tif, FIELD_COLORMAP)) + { + if (!TIFFWriteDirectoryTagColormap(tif, &ndir, dir)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES)) + { + if (tif->tif_dir.td_extrasamples) + { + uint16_t na; + uint16_t *nb; + TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &na, &nb); + if (!TIFFWriteDirectoryTagShortArray( + tif, &ndir, dir, TIFFTAG_EXTRASAMPLES, na, nb)) + goto bad; + } + } + if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT)) + { + if (!TIFFWriteDirectoryTagShortPerSample( + tif, &ndir, dir, TIFFTAG_SAMPLEFORMAT, + tif->tif_dir.td_sampleformat)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagSampleformatArray( + tif, &ndir, dir, TIFFTAG_SMINSAMPLEVALUE, + tif->tif_dir.td_samplesperpixel, + tif->tif_dir.td_sminsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE)) + { + if (!TIFFWriteDirectoryTagSampleformatArray( + tif, &ndir, dir, TIFFTAG_SMAXSAMPLEVALUE, + tif->tif_dir.td_samplesperpixel, + tif->tif_dir.td_smaxsamplevalue)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH)) + { + if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, + TIFFTAG_IMAGEDEPTH, + tif->tif_dir.td_imagedepth)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_TILEDEPTH)) + { + if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, + TIFFTAG_TILEDEPTH, + tif->tif_dir.td_tiledepth)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS)) + { + if (!TIFFWriteDirectoryTagShortArray( + tif, &ndir, dir, TIFFTAG_HALFTONEHINTS, 2, + &tif->tif_dir.td_halftonehints[0])) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING)) + { + if (!TIFFWriteDirectoryTagShortArray( + tif, &ndir, dir, TIFFTAG_YCBCRSUBSAMPLING, 2, + &tif->tif_dir.td_ycbcrsubsampling[0])) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING)) + { + if (!TIFFWriteDirectoryTagShort( + tif, &ndir, dir, TIFFTAG_YCBCRPOSITIONING, + tif->tif_dir.td_ycbcrpositioning)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE)) + { + if (!TIFFWriteDirectoryTagRationalArray( + tif, &ndir, dir, TIFFTAG_REFERENCEBLACKWHITE, 6, + tif->tif_dir.td_refblackwhite)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION)) + { + if (!TIFFWriteDirectoryTagTransferfunction(tif, &ndir, dir)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_INKNAMES)) + { + if (!TIFFWriteDirectoryTagAscii( + tif, &ndir, dir, TIFFTAG_INKNAMES, + tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) + { + if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, + TIFFTAG_NUMBEROFINKS, + tif->tif_dir.td_numberofinks)) + goto bad; + } + if (TIFFFieldSet(tif, FIELD_SUBIFD)) + { + if (!TIFFWriteDirectoryTagSubifd(tif, &ndir, dir)) + goto bad; + } + { + uint32_t n; + for (n = 0; n < tif->tif_nfields; n++) + { + const TIFFField *o; + o = tif->tif_fields[n]; + if ((o->field_bit >= FIELD_CODEC) && + (TIFFFieldSet(tif, o->field_bit))) + { + switch (o->get_field_type) + { + case TIFF_SETGET_ASCII: + { + uint32_t pa; + char *pb; + assert(o->field_type == TIFF_ASCII); + assert(o->field_readcount == TIFF_VARIABLE); + assert(o->field_passcount == 0); + TIFFGetField(tif, o->field_tag, &pb); + pa = (uint32_t)(strlen(pb)); + if (!TIFFWriteDirectoryTagAscii( + tif, &ndir, dir, (uint16_t)o->field_tag, + pa, pb)) + goto bad; + } + break; + case TIFF_SETGET_UINT16: + { + uint16_t p; + assert(o->field_type == TIFF_SHORT); + assert(o->field_readcount == 1); + assert(o->field_passcount == 0); + TIFFGetField(tif, o->field_tag, &p); + if (!TIFFWriteDirectoryTagShort( + tif, &ndir, dir, (uint16_t)o->field_tag, + p)) goto bad; - } - if (nb->tdir_tag==TIFFTAG_SUBIFD) - break; - } - if (!(tif->tif_flags&TIFF_BIGTIFF)) - tif->tif_subifdoff=tif->tif_diroff+2+na*12+8; - else - tif->tif_subifdoff=tif->tif_diroff+8+na*20+12; - } - } - dirmem=_TIFFmallocExt(tif, dirsize); - if (dirmem==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - goto bad; - } - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint8_t* n; - uint32_t nTmp; - TIFFDirEntry* o; - n=dirmem; - *(uint16_t*)n=(uint16_t)ndir; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)n); - n+=2; - o=dir; - for (m=0; m<ndir; m++) - { - *(uint16_t*)n=o->tdir_tag; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)n); - n+=2; - *(uint16_t*)n=o->tdir_type; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)n); - n+=2; - nTmp = (uint32_t)o->tdir_count; - _TIFFmemcpy(n,&nTmp,4); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong((uint32_t*)n); - n+=4; - /* This is correct. The data has been */ - /* swabbed previously in TIFFWriteDirectoryTagData */ - _TIFFmemcpy(n,&o->tdir_offset,4); - n+=4; - o++; - } - nTmp = (uint32_t)tif->tif_nextdiroff; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&nTmp); - _TIFFmemcpy(n,&nTmp,4); - } - else - { - uint8_t* n; - TIFFDirEntry* o; - n=dirmem; - *(uint64_t*)n=ndir; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)n); - n+=8; - o=dir; - for (m=0; m<ndir; m++) - { - *(uint16_t*)n=o->tdir_tag; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)n); - n+=2; - *(uint16_t*)n=o->tdir_type; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort((uint16_t*)n); - n+=2; - _TIFFmemcpy(n,&o->tdir_count,8); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)n); - n+=8; - _TIFFmemcpy(n,&o->tdir_offset,8); - n+=8; - o++; - } - _TIFFmemcpy(n,&tif->tif_nextdiroff,8); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8((uint64_t*)n); - } - _TIFFfreeExt(tif, dir); - dir=NULL; - if (!SeekOK(tif,tif->tif_diroff)) - { - TIFFErrorExtR(tif,module,"IO error writing directory"); - goto bad; - } - if (!WriteOK(tif,dirmem,(tmsize_t)dirsize)) - { - TIFFErrorExtR(tif,module,"IO error writing directory"); - goto bad; - } - _TIFFfreeExt(tif, dirmem); - if (imagedone) - { - TIFFFreeDirectory(tif); - tif->tif_flags &= ~TIFF_DIRTYDIRECT; - tif->tif_flags &= ~TIFF_DIRTYSTRIP; - (*tif->tif_cleanup)(tif); - /* - * Reset directory-related state for subsequent - * directories. - */ - TIFFCreateDirectory(tif); - } - return(1); + } + break; + case TIFF_SETGET_UINT32: + { + uint32_t p; + assert(o->field_type == TIFF_LONG); + assert(o->field_readcount == 1); + assert(o->field_passcount == 0); + TIFFGetField(tif, o->field_tag, &p); + if (!TIFFWriteDirectoryTagLong( + tif, &ndir, dir, (uint16_t)o->field_tag, + p)) + goto bad; + } + break; + case TIFF_SETGET_C32_UINT8: + { + uint32_t pa; + void *pb; + assert(o->field_type == TIFF_UNDEFINED); + assert(o->field_readcount == TIFF_VARIABLE2); + assert(o->field_passcount == 1); + TIFFGetField(tif, o->field_tag, &pa, &pb); + if (!TIFFWriteDirectoryTagUndefinedArray( + tif, &ndir, dir, (uint16_t)o->field_tag, + pa, pb)) + goto bad; + } + break; + default: + TIFFErrorExtR( + tif, module, + "Cannot write tag %" PRIu32 " (%s)", + TIFFFieldTag(o), + o->field_name ? o->field_name : "unknown"); + goto bad; + } + } + } + } + } + for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++) + { + uint16_t tag = + (uint16_t)tif->tif_dir.td_customValues[m].info->field_tag; + uint32_t count = tif->tif_dir.td_customValues[m].count; + switch (tif->tif_dir.td_customValues[m].info->field_type) + { + case TIFF_ASCII: + if (!TIFFWriteDirectoryTagAscii( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_UNDEFINED: + if (!TIFFWriteDirectoryTagUndefinedArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_BYTE: + if (!TIFFWriteDirectoryTagByteArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SBYTE: + if (!TIFFWriteDirectoryTagSbyteArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SHORT: + if (!TIFFWriteDirectoryTagShortArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SSHORT: + if (!TIFFWriteDirectoryTagSshortArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_LONG: + if (!TIFFWriteDirectoryTagLongArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SLONG: + if (!TIFFWriteDirectoryTagSlongArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_LONG8: + if (!TIFFWriteDirectoryTagLong8Array( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_SLONG8: + if (!TIFFWriteDirectoryTagSlong8Array( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_RATIONAL: + { + /*-- Rational2Double: For Rationals evaluate + * "set_field_type" to determine internal storage size. */ + int tv_size; + tv_size = TIFFFieldSetGetSize( + tif->tif_dir.td_customValues[m].info); + if (tv_size == 8) + { + if (!TIFFWriteDirectoryTagRationalDoubleArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + } + else + { + /*-- default should be tv_size == 4 */ + if (!TIFFWriteDirectoryTagRationalArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + /*-- ToDo: After Testing, this should be removed and + * tv_size==4 should be set as default. */ + if (tv_size != 4) + { + TIFFErrorExtR(tif, + "TIFFLib: _TIFFWriteDirectorySec()", + "Rational2Double: .set_field_type is " + "not 4 but %d", + tv_size); + } + } + } + break; + case TIFF_SRATIONAL: + { + /*-- Rational2Double: For Rationals evaluate + * "set_field_type" to determine internal storage size. */ + int tv_size; + tv_size = TIFFFieldSetGetSize( + tif->tif_dir.td_customValues[m].info); + if (tv_size == 8) + { + if (!TIFFWriteDirectoryTagSrationalDoubleArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + } + else + { + /*-- default should be tv_size == 4 */ + if (!TIFFWriteDirectoryTagSrationalArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + /*-- ToDo: After Testing, this should be removed and + * tv_size==4 should be set as default. */ + if (tv_size != 4) + { + TIFFErrorExtR(tif, + "TIFFLib: _TIFFWriteDirectorySec()", + "Rational2Double: .set_field_type is " + "not 4 but %d", + tv_size); + } + } + } + break; + case TIFF_FLOAT: + if (!TIFFWriteDirectoryTagFloatArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_DOUBLE: + if (!TIFFWriteDirectoryTagDoubleArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_IFD: + if (!TIFFWriteDirectoryTagIfdArray( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + case TIFF_IFD8: + if (!TIFFWriteDirectoryTagIfdIfd8Array( + tif, &ndir, dir, tag, count, + tif->tif_dir.td_customValues[m].value)) + goto bad; + break; + default: + assert(0); /* we should never get here */ + break; + } + } + if (dir != NULL) + break; + dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry)); + if (dir == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + goto bad; + } + if (isimage) + { + if ((tif->tif_diroff == 0) && (!TIFFLinkDirectory(tif))) + goto bad; + } + else + tif->tif_diroff = + (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1)); + if (pdiroff != NULL) + *pdiroff = tif->tif_diroff; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + dirsize = 2 + ndir * 12 + 4; + else + dirsize = 8 + ndir * 20 + 8; + tif->tif_dataoff = tif->tif_diroff + dirsize; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + tif->tif_dataoff = (uint32_t)tif->tif_dataoff; + if ((tif->tif_dataoff < tif->tif_diroff) || + (tif->tif_dataoff < (uint64_t)dirsize)) + { + TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); + goto bad; + } + if (tif->tif_dataoff & 1) + tif->tif_dataoff++; + if (isimage) + tif->tif_curdir++; + } + if (isimage) + { + if (TIFFFieldSet(tif, FIELD_SUBIFD) && (tif->tif_subifdoff == 0)) + { + uint32_t na; + TIFFDirEntry *nb; + for (na = 0, nb = dir;; na++, nb++) + { + if (na == ndir) + { + TIFFErrorExtR(tif, module, "Cannot find SubIFD tag"); + goto bad; + } + if (nb->tdir_tag == TIFFTAG_SUBIFD) + break; + } + if (!(tif->tif_flags & TIFF_BIGTIFF)) + tif->tif_subifdoff = tif->tif_diroff + 2 + na * 12 + 8; + else + tif->tif_subifdoff = tif->tif_diroff + 8 + na * 20 + 12; + } + } + dirmem = _TIFFmallocExt(tif, dirsize); + if (dirmem == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + goto bad; + } + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint8_t *n; + uint32_t nTmp; + TIFFDirEntry *o; + n = dirmem; + *(uint16_t *)n = (uint16_t)ndir; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)n); + n += 2; + o = dir; + for (m = 0; m < ndir; m++) + { + *(uint16_t *)n = o->tdir_tag; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)n); + n += 2; + *(uint16_t *)n = o->tdir_type; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)n); + n += 2; + nTmp = (uint32_t)o->tdir_count; + _TIFFmemcpy(n, &nTmp, 4); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)n); + n += 4; + /* This is correct. The data has been */ + /* swabbed previously in TIFFWriteDirectoryTagData */ + _TIFFmemcpy(n, &o->tdir_offset, 4); + n += 4; + o++; + } + nTmp = (uint32_t)tif->tif_nextdiroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nTmp); + _TIFFmemcpy(n, &nTmp, 4); + } + else + { + uint8_t *n; + TIFFDirEntry *o; + n = dirmem; + *(uint64_t *)n = ndir; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)n); + n += 8; + o = dir; + for (m = 0; m < ndir; m++) + { + *(uint16_t *)n = o->tdir_tag; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)n); + n += 2; + *(uint16_t *)n = o->tdir_type; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)n); + n += 2; + _TIFFmemcpy(n, &o->tdir_count, 8); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)n); + n += 8; + _TIFFmemcpy(n, &o->tdir_offset, 8); + n += 8; + o++; + } + _TIFFmemcpy(n, &tif->tif_nextdiroff, 8); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)n); + } + _TIFFfreeExt(tif, dir); + dir = NULL; + if (!SeekOK(tif, tif->tif_diroff)) + { + TIFFErrorExtR(tif, module, "IO error writing directory"); + goto bad; + } + if (!WriteOK(tif, dirmem, (tmsize_t)dirsize)) + { + TIFFErrorExtR(tif, module, "IO error writing directory"); + goto bad; + } + _TIFFfreeExt(tif, dirmem); + if (imagedone) + { + TIFFFreeDirectory(tif); + tif->tif_flags &= ~TIFF_DIRTYDIRECT; + tif->tif_flags &= ~TIFF_DIRTYSTRIP; + (*tif->tif_cleanup)(tif); + /* + * Reset directory-related state for subsequent + * directories. + */ + TIFFCreateDirectory(tif); + } + return (1); bad: - if (dir!=NULL) - _TIFFfreeExt(tif, dir); - if (dirmem!=NULL) - _TIFFfreeExt(tif, dirmem); - return(0); + if (dir != NULL) + _TIFFfreeExt(tif, dir); + if (dirmem != NULL) + _TIFFfreeExt(tif, dirmem); + return (0); } -static int8_t TIFFClampDoubleToInt8(double val ) +static int8_t TIFFClampDoubleToInt8(double val) { - if( val > 127 ) + if (val > 127) return 127; - if( val < -128 || val != val ) + if (val < -128 || val != val) return -128; return (int8_t)val; } -static int16_t TIFFClampDoubleToInt16(double val ) +static int16_t TIFFClampDoubleToInt16(double val) { - if( val > 32767 ) + if (val > 32767) return 32767; - if( val < -32768 || val != val ) + if (val < -32768 || val != val) return -32768; return (int16_t)val; } -static int32_t TIFFClampDoubleToInt32(double val ) +static int32_t TIFFClampDoubleToInt32(double val) { - if( val > 0x7FFFFFFF ) + if (val > 0x7FFFFFFF) return 0x7FFFFFFF; - if( val < -0x7FFFFFFF-1 || val != val ) - return -0x7FFFFFFF-1; + if (val < -0x7FFFFFFF - 1 || val != val) + return -0x7FFFFFFF - 1; return (int32_t)val; } -static uint8_t TIFFClampDoubleToUInt8(double val ) +static uint8_t TIFFClampDoubleToUInt8(double val) { - if( val < 0 ) + if (val < 0) return 0; - if( val > 255 || val != val ) + if (val > 255 || val != val) return 255; return (uint8_t)val; } -static uint16_t TIFFClampDoubleToUInt16(double val ) +static uint16_t TIFFClampDoubleToUInt16(double val) { - if( val < 0 ) + if (val < 0) return 0; - if( val > 65535 || val != val ) + if (val > 65535 || val != val) return 65535; return (uint16_t)val; } -static uint32_t TIFFClampDoubleToUInt32(double val ) +static uint32_t TIFFClampDoubleToUInt32(double val) { - if( val < 0 ) + if (val < 0) return 0; - if( val > 0xFFFFFFFFU || val != val ) + if (val > 0xFFFFFFFFU || val != val) return 0xFFFFFFFFU; return (uint32_t)val; } -static int -TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value) -{ - static const char module[] = "TIFFWriteDirectoryTagSampleformatArray"; - void* conv; - uint32_t i; - int ok; - conv = _TIFFmallocExt(tif, count*sizeof(double)); - if (conv == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return (0); - } - - switch (tif->tif_dir.td_sampleformat) - { - case SAMPLEFORMAT_IEEEFP: - if (tif->tif_dir.td_bitspersample<=32) - { - for (i = 0; i < count; ++i) - ((float*)conv)[i] = _TIFFClampDoubleToFloat(value[i]); - ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv); - } - else - { - ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value); - } - break; - case SAMPLEFORMAT_INT: - if (tif->tif_dir.td_bitspersample<=8) - { - for (i = 0; i < count; ++i) - ((int8_t*)conv)[i] = TIFFClampDoubleToInt8(value[i]); - ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8_t*)conv); - } - else if (tif->tif_dir.td_bitspersample<=16) - { - for (i = 0; i < count; ++i) - ((int16_t*)conv)[i] = TIFFClampDoubleToInt16(value[i]); - ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16_t*)conv); - } - else - { - for (i = 0; i < count; ++i) - ((int32_t*)conv)[i] = TIFFClampDoubleToInt32(value[i]); - ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32_t*)conv); - } - break; - case SAMPLEFORMAT_UINT: - if (tif->tif_dir.td_bitspersample<=8) - { - for (i = 0; i < count; ++i) - ((uint8_t*)conv)[i] = TIFFClampDoubleToUInt8(value[i]); - ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8_t*)conv); - } - else if (tif->tif_dir.td_bitspersample<=16) - { - for (i = 0; i < count; ++i) - ((uint16_t*)conv)[i] = TIFFClampDoubleToUInt16(value[i]); - ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16_t*)conv); - } - else - { - for (i = 0; i < count; ++i) - ((uint32_t*)conv)[i] = TIFFClampDoubleToUInt32(value[i]); - ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32_t*)conv); - } - break; - default: - ok = 0; - } - - _TIFFfreeExt(tif, conv); - return (ok); +static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + double *value) +{ + static const char module[] = "TIFFWriteDirectoryTagSampleformatArray"; + void *conv; + uint32_t i; + int ok; + conv = _TIFFmallocExt(tif, count * sizeof(double)); + if (conv == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + + switch (tif->tif_dir.td_sampleformat) + { + case SAMPLEFORMAT_IEEEFP: + if (tif->tif_dir.td_bitspersample <= 32) + { + for (i = 0; i < count; ++i) + ((float *)conv)[i] = _TIFFClampDoubleToFloat(value[i]); + ok = TIFFWriteDirectoryTagFloatArray(tif, ndir, dir, tag, count, + (float *)conv); + } + else + { + ok = TIFFWriteDirectoryTagDoubleArray(tif, ndir, dir, tag, + count, value); + } + break; + case SAMPLEFORMAT_INT: + if (tif->tif_dir.td_bitspersample <= 8) + { + for (i = 0; i < count; ++i) + ((int8_t *)conv)[i] = TIFFClampDoubleToInt8(value[i]); + ok = TIFFWriteDirectoryTagSbyteArray(tif, ndir, dir, tag, count, + (int8_t *)conv); + } + else if (tif->tif_dir.td_bitspersample <= 16) + { + for (i = 0; i < count; ++i) + ((int16_t *)conv)[i] = TIFFClampDoubleToInt16(value[i]); + ok = TIFFWriteDirectoryTagSshortArray(tif, ndir, dir, tag, + count, (int16_t *)conv); + } + else + { + for (i = 0; i < count; ++i) + ((int32_t *)conv)[i] = TIFFClampDoubleToInt32(value[i]); + ok = TIFFWriteDirectoryTagSlongArray(tif, ndir, dir, tag, count, + (int32_t *)conv); + } + break; + case SAMPLEFORMAT_UINT: + if (tif->tif_dir.td_bitspersample <= 8) + { + for (i = 0; i < count; ++i) + ((uint8_t *)conv)[i] = TIFFClampDoubleToUInt8(value[i]); + ok = TIFFWriteDirectoryTagByteArray(tif, ndir, dir, tag, count, + (uint8_t *)conv); + } + else if (tif->tif_dir.td_bitspersample <= 16) + { + for (i = 0; i < count; ++i) + ((uint16_t *)conv)[i] = TIFFClampDoubleToUInt16(value[i]); + ok = TIFFWriteDirectoryTagShortArray(tif, ndir, dir, tag, count, + (uint16_t *)conv); + } + else + { + for (i = 0; i < count; ++i) + ((uint32_t *)conv)[i] = TIFFClampDoubleToUInt32(value[i]); + ok = TIFFWriteDirectoryTagLongArray(tif, ndir, dir, tag, count, + (uint32_t *)conv); + } + break; + default: + ok = 0; + } + + _TIFFfreeExt(tif, conv); + return (ok); } -static int -TIFFWriteDirectoryTagAscii(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, char* value) +static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, char *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return ( + TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value)); } -static int -TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value) +static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint8_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedUndefinedArray(tif, ndir, dir, tag, + count, value)); } -static int -TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value) +static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint8_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedByteArray(tif, ndir, dir, tag, count, + value)); } -static int -TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int8_t* value) +static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int8_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedSbyteArray(tif, ndir, dir, tag, count, + value)); } -static int -TIFFWriteDirectoryTagShort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value) +static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value)); } -static int -TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint16_t* value) +static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint16_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count, + value)); } -static int -TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value) -{ - static const char module[] = "TIFFWriteDirectoryTagShortPerSample"; - uint16_t* m; - uint16_t* na; - uint16_t nb; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=_TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel*sizeof(uint16_t)); - if (m==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++) - *na=value; - o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m); - _TIFFfreeExt(tif, m); - return(o); +static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value) +{ + static const char module[] = "TIFFWriteDirectoryTagShortPerSample"; + uint16_t *m; + uint16_t *na; + uint16_t nb; + int o; + if (dir == NULL) + { + (*ndir)++; + return (1); + } + m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t)); + if (m == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + for (na = m, nb = 0; nb < tif->tif_dir.td_samplesperpixel; na++, nb++) + *na = value; + o = TIFFWriteDirectoryTagCheckedShortArray( + tif, ndir, dir, tag, tif->tif_dir.td_samplesperpixel, m); + _TIFFfreeExt(tif, m); + return (o); } -static int -TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int16_t* value) +static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int16_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedSshortArray(tif, ndir, dir, tag, count, + value)); } -static int -TIFFWriteDirectoryTagLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value) +static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value)); } -static int -TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value) +static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint32_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, + value)); } -static int -TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int32_t* value) +static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int32_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, + value)); } /************************************************************************/ @@ -1245,54 +1548,59 @@ TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, ui /* */ /* Write either Long8 or Long array depending on file type. */ /************************************************************************/ -static int -TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value) -{ - static const char module[] = "TIFFWriteDirectoryTagLong8Array"; - uint64_t *ma; - uint32_t mb; - uint32_t *p; - uint32_t *q; - int o; - - /* is this just a counting pass? */ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - - /* We always write Long8 for BigTIFF, no checking needed. */ - if (tif->tif_flags & TIFF_BIGTIFF) - return(TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag, count, value)); - - /* - ** For classic tiff we want to verify everything is in range for long - ** and convert to long format. - */ - p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); - if (p == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return(0); - } - - for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) - { - if (*ma > 0xFFFFFFFF) - { - TIFFErrorExtR(tif, module, - "Attempt to write unsigned long value %"PRIu64" larger than 0xFFFFFFFF for tag %d in Classic TIFF file. TIFF file writing aborted", *ma, tag); - _TIFFfreeExt(tif, p); - return(0); - } - *q = (uint32_t)(*ma); - } - - o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p); - _TIFFfreeExt(tif, p); - - return(o); +static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value) +{ + static const char module[] = "TIFFWriteDirectoryTagLong8Array"; + uint64_t *ma; + uint32_t mb; + uint32_t *p; + uint32_t *q; + int o; + + /* is this just a counting pass? */ + if (dir == NULL) + { + (*ndir)++; + return (1); + } + + /* We always write Long8 for BigTIFF, no checking needed. */ + if (tif->tif_flags & TIFF_BIGTIFF) + return (TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag, + count, value)); + + /* + ** For classic tiff we want to verify everything is in range for long + ** and convert to long format. + */ + p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); + if (p == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + + for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) + { + if (*ma > 0xFFFFFFFF) + { + TIFFErrorExtR(tif, module, + "Attempt to write unsigned long value %" PRIu64 + " larger than 0xFFFFFFFF for tag %d in Classic TIFF " + "file. TIFF file writing aborted", + *ma, tag); + _TIFFfreeExt(tif, p); + return (0); + } + *q = (uint32_t)(*ma); + } + + o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p); + _TIFFfreeExt(tif, p); + + return (o); } /************************************************************************/ @@ -1300,178 +1608,210 @@ TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, ui /* */ /* Write either SLong8 or SLong array depending on file type. */ /************************************************************************/ -static int -TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int64_t* value) -{ - static const char module[] = "TIFFWriteDirectoryTagSlong8Array"; - int64_t *ma; - uint32_t mb; - int32_t *p; - int32_t *q; - int o; - - /* is this just a counting pass? */ - if (dir==NULL) - { - (*ndir)++; - return(1); - } - /* We always write SLong8 for BigTIFF, no checking needed. */ - if (tif->tif_flags & TIFF_BIGTIFF) - return(TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag, count, value)); - - /* - ** For classic tiff we want to verify everything is in range for signed-long - ** and convert to signed-long format. - */ - p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); - if (p == NULL) - { - TIFFErrorExtR(tif, module, "Out of memory"); - return(0); - } - - for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) - { - if (*ma > (2147483647)) - { - TIFFErrorExtR(tif, module, - "Attempt to write signed long value %"PRIi64" larger than 0x7FFFFFFF (2147483647) for tag %d in Classic TIFF file. TIFF writing to file aborted", *ma, tag); - _TIFFfreeExt(tif, p); - return(0); - } else if (*ma < (-2147483647 - 1)) - { - TIFFErrorExtR(tif, module, - "Attempt to write signed long value %"PRIi64" smaller than 0x80000000 (-2147483648) for tag %d in Classic TIFF file. TIFF writing to file aborted", *ma, tag); - _TIFFfreeExt(tif, p); - return(0); - } - *q = (int32_t)(*ma); - } - - o = TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, p); - _TIFFfreeExt(tif, p); - - return(o); +static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, int64_t *value) +{ + static const char module[] = "TIFFWriteDirectoryTagSlong8Array"; + int64_t *ma; + uint32_t mb; + int32_t *p; + int32_t *q; + int o; + + /* is this just a counting pass? */ + if (dir == NULL) + { + (*ndir)++; + return (1); + } + /* We always write SLong8 for BigTIFF, no checking needed. */ + if (tif->tif_flags & TIFF_BIGTIFF) + return (TIFFWriteDirectoryTagCheckedSlong8Array(tif, ndir, dir, tag, + count, value)); + + /* + ** For classic tiff we want to verify everything is in range for signed-long + ** and convert to signed-long format. + */ + p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); + if (p == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + + for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) + { + if (*ma > (2147483647)) + { + TIFFErrorExtR(tif, module, + "Attempt to write signed long value %" PRIi64 + " larger than 0x7FFFFFFF (2147483647) for tag %d in " + "Classic TIFF file. TIFF writing to file aborted", + *ma, tag); + _TIFFfreeExt(tif, p); + return (0); + } + else if (*ma < (-2147483647 - 1)) + { + TIFFErrorExtR(tif, module, + "Attempt to write signed long value %" PRIi64 + " smaller than 0x80000000 (-2147483648) for tag %d " + "in Classic TIFF file. TIFF writing to file aborted", + *ma, tag); + _TIFFfreeExt(tif, p); + return (0); + } + *q = (int32_t)(*ma); + } + + o = TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, p); + _TIFFfreeExt(tif, p); + + return (o); } -static int -TIFFWriteDirectoryTagRational(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value) +static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + double value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedRational(tif, ndir, dir, tag, value)); } -static int -TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value) +static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedRationalArray(tif, ndir, dir, tag, + count, value)); } -static int -TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value) +static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedSrationalArray(tif, ndir, dir, tag, + count, value)); } /*-- Rational2Double: additional write functions */ -static int -TIFFWriteDirectoryTagRationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value) +static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + double *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif, ndir, dir, tag, + count, value)); } -static int -TIFFWriteDirectoryTagSrationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value) +static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + double *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedSrationalDoubleArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedSrationalDoubleArray( + tif, ndir, dir, tag, count, value)); } -static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value) +static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, float *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedFloatArray(tif, ndir, dir, tag, count, + value)); } -static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value) +static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, double *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count, + value)); } -static int -TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value) +static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint32_t *value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + return (TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, + value)); } -static int -TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value) +static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value) { - if (dir==NULL) - { - (*ndir)++; - return(1); - } - if (value<=0xFFFF) - return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16_t)value)); - else - return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value)); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + if (value <= 0xFFFF) + return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, + (uint16_t)value)); + else + return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value)); } -static int _WriteAsType(TIFF* tif, uint64_t strile_size, uint64_t uncompressed_threshold) +static int _WriteAsType(TIFF *tif, uint64_t strile_size, + uint64_t uncompressed_threshold) { const uint16_t compression = tif->tif_dir.td_compression; - if ( compression == COMPRESSION_NONE ) + if (compression == COMPRESSION_NONE) { return strile_size > uncompressed_threshold; } - else if ( compression == COMPRESSION_JPEG || - compression == COMPRESSION_LZW || - compression == COMPRESSION_ADOBE_DEFLATE || - compression == COMPRESSION_DEFLATE || - compression == COMPRESSION_LZMA || - compression == COMPRESSION_LERC || - compression == COMPRESSION_ZSTD || - compression == COMPRESSION_WEBP || - compression == COMPRESSION_JXL ) + else if (compression == COMPRESSION_JPEG || + compression == COMPRESSION_LZW || + compression == COMPRESSION_ADOBE_DEFLATE || + compression == COMPRESSION_DEFLATE || + compression == COMPRESSION_LZMA || + compression == COMPRESSION_LERC || + compression == COMPRESSION_ZSTD || + compression == COMPRESSION_WEBP || compression == COMPRESSION_JXL) { /* For a few select compression types, we assume that in the worst */ /* case the compressed size will be 10 times the uncompressed size */ @@ -1481,12 +1821,12 @@ static int _WriteAsType(TIFF* tif, uint64_t strile_size, uint64_t uncompressed_t return 1; } -static int WriteAsLong8(TIFF* tif, uint64_t strile_size) +static int WriteAsLong8(TIFF *tif, uint64_t strile_size) { return _WriteAsType(tif, strile_size, 0xFFFFFFFFU); } -static int WriteAsLong4(TIFF* tif, uint64_t strile_size) +static int WriteAsLong4(TIFF *tif, uint64_t strile_size) { return _WriteAsType(tif, strile_size, 0xFFFFU); } @@ -1498,121 +1838,128 @@ static int WriteAsLong4(TIFF* tif, uint64_t strile_size) /* on strile size and Classic/BigTIFF mode. */ /************************************************************************/ -static int -TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value) +static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value) { static const char module[] = "TIFFWriteDirectoryTagLongLong8Array"; int o; int write_aslong4; /* is this just a counting pass? */ - if (dir==NULL) + if (dir == NULL) { (*ndir)++; - return(1); + return (1); } - if( tif->tif_dir.td_deferstrilearraywriting ) + if (tif->tif_dir.td_deferstrilearraywriting) { - return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0, NULL); + return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0, + NULL); } - if( tif->tif_flags&TIFF_BIGTIFF ) + if (tif->tif_flags & TIFF_BIGTIFF) { int write_aslong8 = 1; /* In the case of ByteCounts array, we may be able to write them on */ /* LONG if the strip/tilesize is not too big. */ - /* Also do that for count > 1 in the case someone would want to create */ + /* Also do that for count > 1 in the case someone would want to create + */ /* a single-strip file with a growing height, in which case using */ /* LONG8 will be safer. */ - if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS ) + if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) { write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif)); } - else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS ) + else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) { write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif)); } - if( write_aslong8 ) + if (write_aslong8) { - return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir, - tag,count,value); + return TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag, + count, value); } } write_aslong4 = 1; - if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS ) + if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) { write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif)); } - else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS ) + else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) { write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif)); } - if( write_aslong4 ) + if (write_aslong4) { /* ** For classic tiff we want to verify everything is in range for LONG ** and convert to long format. */ - uint32_t* p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); - uint32_t* q; - uint64_t* ma; + uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); + uint32_t *q; + uint64_t *ma; uint32_t mb; - if (p==NULL) + if (p == NULL) { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); } - for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++) + for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) { - if (*ma>0xFFFFFFFF) + if (*ma > 0xFFFFFFFF) { - TIFFErrorExtR(tif,module, - "Attempt to write value larger than 0xFFFFFFFF in LONG array."); + TIFFErrorExtR(tif, module, + "Attempt to write value larger than 0xFFFFFFFF " + "in LONG array."); _TIFFfreeExt(tif, p); - return(0); + return (0); } - *q= (uint32_t)(*ma); + *q = (uint32_t)(*ma); } - o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p); + o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, + p); _TIFFfreeExt(tif, p); } else { - uint16_t* p = _TIFFmallocExt(tif, count * sizeof(uint16_t)); - uint16_t* q; - uint64_t* ma; + uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t)); + uint16_t *q; + uint64_t *ma; uint32_t mb; - if (p==NULL) + if (p == NULL) { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); } - for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++) + for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) { - if (*ma>0xFFFF) + if (*ma > 0xFFFF) { /* Should not happen normally given the check we did before */ - TIFFErrorExtR(tif,module, - "Attempt to write value larger than 0xFFFF in SHORT array."); + TIFFErrorExtR(tif, module, + "Attempt to write value larger than 0xFFFF in " + "SHORT array."); _TIFFfreeExt(tif, p); - return(0); + return (0); } - *q= (uint16_t)(*ma); + *q = (uint16_t)(*ma); } - o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p); + o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count, + p); _TIFFfreeExt(tif, p); } - return(o); + return (o); } /************************************************************************/ @@ -1621,469 +1968,548 @@ TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir /* Write either IFD8 or IFD array depending on file type. */ /************************************************************************/ -static int -TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value) +static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint64_t *value) { static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array"; - uint64_t* ma; + uint64_t *ma; uint32_t mb; - uint32_t* p; - uint32_t* q; + uint32_t *p; + uint32_t *q; int o; /* is this just a counting pass? */ - if (dir==NULL) + if (dir == NULL) { (*ndir)++; - return(1); + return (1); } /* We always write IFD8 for BigTIFF, no checking needed. */ - if( tif->tif_flags&TIFF_BIGTIFF ) - return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir, - tag,count,value); + if (tif->tif_flags & TIFF_BIGTIFF) + return TIFFWriteDirectoryTagCheckedIfd8Array(tif, ndir, dir, tag, count, + value); /* ** For classic tiff we want to verify everything is in range for IFD ** and convert to long format. */ - p = _TIFFmallocExt(tif, count*sizeof(uint32_t)); - if (p==NULL) + p = _TIFFmallocExt(tif, count * sizeof(uint32_t)); + if (p == NULL) { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); } - for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++) + for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++) { - if (*ma>0xFFFFFFFF) + if (*ma > 0xFFFFFFFF) { - TIFFErrorExtR(tif,module, - "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file."); + TIFFErrorExtR(tif, module, + "Attempt to write value larger than 0xFFFFFFFF in " + "Classic TIFF file."); _TIFFfreeExt(tif, p); - return(0); + return (0); } - *q= (uint32_t)(*ma); + *q = (uint32_t)(*ma); } - o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p); + o = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, p); _TIFFfreeExt(tif, p); - return(o); -} - -static int -TIFFWriteDirectoryTagColormap(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir) -{ - static const char module[] = "TIFFWriteDirectoryTagColormap"; - uint32_t m; - uint16_t* n; - int o; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=(1<<tif->tif_dir.td_bitspersample); - n=_TIFFmallocExt(tif, 3*m*sizeof(uint16_t)); - if (n==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - _TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16_t)); - _TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16_t)); - _TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16_t)); - o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n); - _TIFFfreeExt(tif, n); - return(o); + return (o); } -static int -TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir) -{ - static const char module[] = "TIFFWriteDirectoryTagTransferfunction"; - uint32_t m; - uint16_t n; - uint16_t* o; - int p; - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=(1<<tif->tif_dir.td_bitspersample); - n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples; - /* - * Check if the table can be written as a single column, - * or if it must be written as 3 columns. Note that we - * write a 3-column tag if there are 2 samples/pixel and - * a single column of data won't suffice--hmm. - */ - if (n>3) - n=3; - if (n==3) - { - if (tif->tif_dir.td_transferfunction[2] == NULL || - !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16_t))) - n=2; - } - if (n==2) - { - if (tif->tif_dir.td_transferfunction[1] == NULL || - !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16_t))) - n=1; - } - if (n==0) - n=1; - o=_TIFFmallocExt(tif, n*m*sizeof(uint16_t)); - if (o==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - _TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16_t)); - if (n>1) - _TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16_t)); - if (n>2) - _TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16_t)); - p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o); - _TIFFfreeExt(tif, o); - return(p); -} +static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir) +{ + static const char module[] = "TIFFWriteDirectoryTagColormap"; + uint32_t m; + uint16_t *n; + int o; + if (dir == NULL) + { + (*ndir)++; + return (1); + } + m = (1 << tif->tif_dir.td_bitspersample); + n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t)); + if (n == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + _TIFFmemcpy(&n[0], tif->tif_dir.td_colormap[0], m * sizeof(uint16_t)); + _TIFFmemcpy(&n[m], tif->tif_dir.td_colormap[1], m * sizeof(uint16_t)); + _TIFFmemcpy(&n[2 * m], tif->tif_dir.td_colormap[2], m * sizeof(uint16_t)); + o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, TIFFTAG_COLORMAP, + 3 * m, n); + _TIFFfreeExt(tif, n); + return (o); +} + +static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir) +{ + static const char module[] = "TIFFWriteDirectoryTagTransferfunction"; + uint32_t m; + uint16_t n; + uint16_t *o; + int p; + if (dir == NULL) + { + (*ndir)++; + return (1); + } + m = (1 << tif->tif_dir.td_bitspersample); + n = tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples; + /* + * Check if the table can be written as a single column, + * or if it must be written as 3 columns. Note that we + * write a 3-column tag if there are 2 samples/pixel and + * a single column of data won't suffice--hmm. + */ + if (n > 3) + n = 3; + if (n == 3) + { + if (tif->tif_dir.td_transferfunction[2] == NULL || + !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0], + tif->tif_dir.td_transferfunction[2], + m * sizeof(uint16_t))) + n = 2; + } + if (n == 2) + { + if (tif->tif_dir.td_transferfunction[1] == NULL || + !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0], + tif->tif_dir.td_transferfunction[1], + m * sizeof(uint16_t))) + n = 1; + } + if (n == 0) + n = 1; + o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t)); + if (o == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + _TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0], + m * sizeof(uint16_t)); + if (n > 1) + _TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1], + m * sizeof(uint16_t)); + if (n > 2) + _TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2], + m * sizeof(uint16_t)); + p = TIFFWriteDirectoryTagCheckedShortArray( + tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o); + _TIFFfreeExt(tif, o); + return (p); +} + +static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir) +{ + static const char module[] = "TIFFWriteDirectoryTagSubifd"; + uint64_t m; + int n; + if (tif->tif_dir.td_nsubifd == 0) + return (1); + if (dir == NULL) + { + (*ndir)++; + return (1); + } + m = tif->tif_dataoff; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t *o; + uint64_t *pa; + uint32_t *pb; + uint16_t p; + o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t)); + if (o == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + pa = tif->tif_dir.td_subifd; + pb = o; + for (p = 0; p < tif->tif_dir.td_nsubifd; p++) + { + assert(pa != 0); -static int -TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir) -{ - static const char module[] = "TIFFWriteDirectoryTagSubifd"; - uint64_t m; - int n; - if (tif->tif_dir.td_nsubifd==0) - return(1); - if (dir==NULL) - { - (*ndir)++; - return(1); - } - m=tif->tif_dataoff; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32_t* o; - uint64_t* pa; - uint32_t* pb; - uint16_t p; - o=_TIFFmallocExt(tif, tif->tif_dir.td_nsubifd*sizeof(uint32_t)); - if (o==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - pa=tif->tif_dir.td_subifd; - pb=o; - for (p=0; p < tif->tif_dir.td_nsubifd; p++) - { - assert(pa != 0); - - /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which is illegal) */ - if( *pa > 0xFFFFFFFFUL) - { - TIFFErrorExtR(tif,module,"Illegal value for SubIFD tag"); - _TIFFfreeExt(tif, o); - return(0); - } - *pb++=(uint32_t)(*pa++); - } - n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o); - _TIFFfreeExt(tif, o); - } - else - n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd); - if (!n) - return(0); - /* - * Total hack: if this directory includes a SubIFD - * tag then force the next <n> directories to be - * written as ``sub directories'' of this one. This - * is used to write things like thumbnails and - * image masks that one wants to keep out of the - * normal directory linkage access mechanism. - */ - tif->tif_flags|=TIFF_INSUBIFD; - tif->tif_nsubifd=tif->tif_dir.td_nsubifd; - if (tif->tif_dir.td_nsubifd==1) - tif->tif_subifdoff=0; - else - tif->tif_subifdoff=m; - return(1); + /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which + * is illegal) */ + if (*pa > 0xFFFFFFFFUL) + { + TIFFErrorExtR(tif, module, "Illegal value for SubIFD tag"); + _TIFFfreeExt(tif, o); + return (0); + } + *pb++ = (uint32_t)(*pa++); + } + n = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, TIFFTAG_SUBIFD, + tif->tif_dir.td_nsubifd, o); + _TIFFfreeExt(tif, o); + } + else + n = TIFFWriteDirectoryTagCheckedIfd8Array( + tif, ndir, dir, TIFFTAG_SUBIFD, tif->tif_dir.td_nsubifd, + tif->tif_dir.td_subifd); + if (!n) + return (0); + /* + * Total hack: if this directory includes a SubIFD + * tag then force the next <n> directories to be + * written as ``sub directories'' of this one. This + * is used to write things like thumbnails and + * image masks that one wants to keep out of the + * normal directory linkage access mechanism. + */ + tif->tif_flags |= TIFF_INSUBIFD; + tif->tif_nsubifd = tif->tif_dir.td_nsubifd; + if (tif->tif_dir.td_nsubifd == 1) + tif->tif_subifdoff = 0; + else + tif->tif_subifdoff = m; + return (1); } -static int -TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, char* value) +static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, char *value) { - assert(sizeof(char)==1); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value)); + assert(sizeof(char) == 1); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count, + count, value)); } -static int -TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value) +static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + uint8_t *value) { - assert(sizeof(uint8_t) == 1); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value)); + assert(sizeof(uint8_t) == 1); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_UNDEFINED, + count, count, value)); } -static int -TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value) +static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint8_t *value) { - assert(sizeof(uint8_t) == 1); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value)); + assert(sizeof(uint8_t) == 1); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_BYTE, count, + count, value)); } -static int -TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int8_t* value) +static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int8_t *value) { - assert(sizeof(int8_t) == 1); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value)); + assert(sizeof(int8_t) == 1); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SBYTE, count, + count, value)); } -static int -TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value) +static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t value) { - uint16_t m; - assert(sizeof(uint16_t) == 2); - m=value; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort(&m); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m)); + uint16_t m; + assert(sizeof(uint16_t) == 2); + m = value; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&m); + return ( + TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, 1, 2, &m)); } -static int -TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint16_t* value) +static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint16_t *value) { - assert(count<0x80000000); - assert(sizeof(uint16_t) == 2); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfShort(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value)); + assert(count < 0x80000000); + assert(sizeof(uint16_t) == 2); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count, + count * 2, value)); } -static int -TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int16_t* value) +static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int16_t *value) { - assert(count<0x80000000); - assert(sizeof(int16_t) == 2); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfShort((uint16_t*)value, count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value)); + assert(count < 0x80000000); + assert(sizeof(int16_t) == 2); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort((uint16_t *)value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SSHORT, count, + count * 2, value)); } -static int -TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value) +static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t value) { - uint32_t m; - assert(sizeof(uint32_t) == 4); - m=value; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&m); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m)); + uint32_t m; + assert(sizeof(uint32_t) == 4); + m = value; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&m); + return ( + TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, 1, 4, &m)); } -static int -TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value) +static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint32_t *value) { - assert(count<0x40000000); - assert(sizeof(uint32_t) == 4); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value)); + assert(count < 0x40000000); + assert(sizeof(uint32_t) == 4); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count, + count * 4, value)); } -static int -TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int32_t* value) -{ - assert(count<0x40000000); - assert(sizeof(int32_t) == 4); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t*)value, count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value)); +static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int32_t *value) +{ + assert(count < 0x40000000); + assert(sizeof(int32_t) == 4); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG, count, + count * 4, value)); } -static int -TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value) -{ - assert(count<0x20000000); - assert(sizeof(uint64_t) == 8); - if( !(tif->tif_flags&TIFF_BIGTIFF) ) { - TIFFErrorExtR(tif,"TIFFWriteDirectoryTagCheckedLong8Array","LONG8 not allowed for ClassicTIFF"); - return(0); - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value)); +static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint64_t *value) +{ + assert(count < 0x20000000); + assert(sizeof(uint64_t) == 8); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedLong8Array", + "LONG8 not allowed for ClassicTIFF"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG8, count, + count * 8, value)); } -static int -TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int64_t* value) +static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + int64_t *value) { - assert(count<0x20000000); - assert(sizeof(int64_t) == 8); - if( !(tif->tif_flags&TIFF_BIGTIFF) ) { - TIFFErrorExtR(tif,"TIFFWriteDirectoryTagCheckedSlong8Array","SLONG8 not allowed for ClassicTIFF"); - return(0); - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8((uint64_t*)value, count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value)); + assert(count < 0x20000000); + assert(sizeof(int64_t) == 8); + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedSlong8Array", + "SLONG8 not allowed for ClassicTIFF"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8((uint64_t *)value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG8, count, + count * 8, value)); } -static int -TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value) -{ - static const char module[] = "TIFFWriteDirectoryTagCheckedRational"; - uint32_t m[2]; - assert(sizeof(uint32_t) == 4); - if (value < 0) - { - TIFFErrorExtR(tif, module, "Negative value is illegal"); - return 0; - } - else if (value != value) - { - TIFFErrorExtR(tif, module, "Not-a-number value is illegal"); - return 0; - } - /*--Rational2Double: New function also used for non-custom rational tags. - * However, could be omitted here, because TIFFWriteDirectoryTagCheckedRational() is not used by code for custom tags, - * only by code for named-tiff-tags like FIELD_RESOLUTION and FIELD_POSITION */ - else { - DoubleToRational(value, &m[0], &m[1]); - } - - if (tif->tif_flags&TIFF_SWAB) - { - TIFFSwabLong(&m[0]); - TIFFSwabLong(&m[1]); - } - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0])); -} +static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + double value) +{ + static const char module[] = "TIFFWriteDirectoryTagCheckedRational"; + uint32_t m[2]; + assert(sizeof(uint32_t) == 4); + if (value < 0) + { + TIFFErrorExtR(tif, module, "Negative value is illegal"); + return 0; + } + else if (value != value) + { + TIFFErrorExtR(tif, module, "Not-a-number value is illegal"); + return 0; + } + /*--Rational2Double: New function also used for non-custom rational tags. + * However, could be omitted here, because + * TIFFWriteDirectoryTagCheckedRational() is not used by code for custom + * tags, only by code for named-tiff-tags like FIELD_RESOLUTION and + * FIELD_POSITION */ + else + { + DoubleToRational(value, &m[0], &m[1]); + } -static int -TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value) -{ - static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray"; - uint32_t* m; - float* na; - uint32_t* nb; - uint32_t nc; - int o; - assert(sizeof(uint32_t) == 4); - m=_TIFFmallocExt(tif, count*2*sizeof(uint32_t)); - if (m==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++) - { - DoubleToRational(*na, &nb[0], &nb[1]); - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(m,count*2); - o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]); - _TIFFfreeExt(tif, m); - return(o); + if (tif->tif_flags & TIFF_SWAB) + { + TIFFSwabLong(&m[0]); + TIFFSwabLong(&m[1]); + } + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, 1, 8, + &m[0])); } -static int -TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value) -{ - static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray"; - int32_t* m; - float* na; - int32_t* nb; - uint32_t nc; - int o; - assert(sizeof(int32_t) == 4); - m=_TIFFmallocExt(tif, count*2*sizeof(int32_t)); - if (m==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++) - { - DoubleToSrational(*na, &nb[0], &nb[1]); - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t*)m, count * 2); - o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]); - _TIFFfreeExt(tif, m); - return(o); +static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + float *value) +{ + static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray"; + uint32_t *m; + float *na; + uint32_t *nb; + uint32_t nc; + int o; + assert(sizeof(uint32_t) == 4); + m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t)); + if (m == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) + { + DoubleToRational(*na, &nb[0], &nb[1]); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m, count * 2); + o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count, + count * 8, &m[0]); + _TIFFfreeExt(tif, m); + return (o); +} + +static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, + uint32_t count, + float *value) +{ + static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray"; + int32_t *m; + float *na; + int32_t *nb; + uint32_t nc; + int o; + assert(sizeof(int32_t) == 4); + m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t)); + if (m == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) + { + DoubleToSrational(*na, &nb[0], &nb[1]); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)m, count * 2); + o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count, + count * 8, &m[0]); + _TIFFfreeExt(tif, m); + return (o); } /*-- Rational2Double: additional write functions for double arrays */ static int -TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value) -{ - static const char module[] = "TIFFWriteDirectoryTagCheckedRationalDoubleArray"; - uint32_t* m; - double* na; - uint32_t* nb; - uint32_t nc; - int o; - assert(sizeof(uint32_t) == 4); - m=_TIFFmallocExt(tif, count*2*sizeof(uint32_t)); - if (m==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++) - { - DoubleToRational(*na, &nb[0], &nb[1]); - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(m,count*2); - o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]); - _TIFFfreeExt(tif, m); - return(o); +TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, double *value) +{ + static const char module[] = + "TIFFWriteDirectoryTagCheckedRationalDoubleArray"; + uint32_t *m; + double *na; + uint32_t *nb; + uint32_t nc; + int o; + assert(sizeof(uint32_t) == 4); + m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t)); + if (m == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) + { + DoubleToRational(*na, &nb[0], &nb[1]); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(m, count * 2); + o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count, + count * 8, &m[0]); + _TIFFfreeExt(tif, m); + return (o); } /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */ -static int -TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value) -{ - static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalDoubleArray"; - int32_t* m; - double* na; - int32_t* nb; - uint32_t nc; - int o; - assert(sizeof(int32_t) == 4); - m=_TIFFmallocExt(tif, count*2*sizeof(int32_t)); - if (m==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++) - { - DoubleToSrational(*na, &nb[0], &nb[1]); - } - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong((uint32_t*)m, count * 2); - o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]); - _TIFFfreeExt(tif, m); - return(o); +static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray( + TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count, + double *value) +{ + static const char module[] = + "TIFFWriteDirectoryTagCheckedSrationalDoubleArray"; + int32_t *m; + double *na; + int32_t *nb; + uint32_t nc; + int o; + assert(sizeof(int32_t) == 4); + m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t)); + if (m == NULL) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++) + { + DoubleToSrational(*na, &nb[0], &nb[1]); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong((uint32_t *)m, count * 2); + o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count, + count * 8, &m[0]); + _TIFFfreeExt(tif, m); + return (o); } /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */ -/** ----- Rational2Double: Double To Rational Conversion ---------------------------------------------------------- -* There is a mathematical theorem to convert real numbers into a rational (integer fraction) number. -* This is called "continuous fraction" which uses the Euclidean algorithm to find the greatest common divisor (GCD). -* (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or https://en.wikipedia.org/wiki/Continued_fraction +/** ----- Rational2Double: Double To Rational Conversion +---------------------------------------------------------- +* There is a mathematical theorem to convert real numbers into a rational +(integer fraction) number. +* This is called "continuous fraction" which uses the Euclidean algorithm to +find the greatest common divisor (GCD). +* (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or +https://en.wikipedia.org/wiki/Continued_fraction * https://en.wikipedia.org/wiki/Euclidean_algorithm) * The following functions implement the -* - ToRationalEuclideanGCD() auxiliary function which mainly implements euclidean GCD -* - DoubleToRational() conversion function for un-signed rationals +* - ToRationalEuclideanGCD() auxiliary function which mainly +implements euclidean GCD +* - DoubleToRational() conversion function for un-signed +rationals * - DoubleToSrational() conversion function for signed rationals ------------------------------------------------------------------------------------------------------------------*/ @@ -2091,561 +2517,627 @@ TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFF * Calculates the rational fractional of a double input value * using the Euclidean algorithm to find the greatest common divisor (GCD) ------------------------------------------------------------------------*/ -static -void ToRationalEuclideanGCD(double value, int blnUseSignedRange, int blnUseSmallRange, uint64_t *ullNum, uint64_t *ullDenom) -{ - /* Internally, the integer variables can be bigger than the external ones, - * as long as the result will fit into the external variable size. - */ - uint64_t numSum[3] = { 0, 1, 0 }, denomSum[3] = { 1, 0, 0 }; - uint64_t aux, bigNum, bigDenom; - uint64_t returnLimit; - int i; - uint64_t nMax; - double fMax; - unsigned long maxDenom; - /*-- nMax and fMax defines the initial accuracy of the starting fractional, - * or better, the highest used integer numbers used within the starting fractional (bigNum/bigDenom). - * There are two approaches, which can accidentally lead to different accuracies just depending on the value. - * Therefore, blnUseSmallRange steers this behavior. - * For long long nMax = ((9223372036854775807-1)/2); for long nMax = ((2147483647-1)/2); - */ - if (blnUseSmallRange) { - nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */ - } - else { - nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */ - } - fMax = (double)nMax; - - /*-- For the Euclidean GCD define the denominator range, so that it stays within size of unsigned long variables. - * maxDenom should be LONG_MAX for negative values and ULONG_MAX for positive ones. - * Also the final returned value of ullNum and ullDenom is limited according to signed- or unsigned-range. - */ - if (blnUseSignedRange) { - maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/ - returnLimit = maxDenom; - } - else { - maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/ - returnLimit = maxDenom; - } - - /*-- First generate a rational fraction (bigNum/bigDenom) which represents the value - * as a rational number with the highest accuracy. Therefore, uint64_t (uint64_t) is needed. - * This rational fraction is then reduced using the Euclidean algorithm to find the greatest common divisor (GCD). - * bigNum = big numinator of value without fraction (or cut residual fraction) - * bigDenom = big denominator of value - *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error and bigDenom has no overflow, - * and stop with enlargement of fraction when the double-value of it reaches an integer number without fractional part. - */ - bigDenom = 1; - while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax)) { - bigDenom <<= 1; - value *= 2; - } - bigNum = (uint64_t)value; - - /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) -- */ +static void ToRationalEuclideanGCD(double value, int blnUseSignedRange, + int blnUseSmallRange, uint64_t *ullNum, + uint64_t *ullDenom) +{ + /* Internally, the integer variables can be bigger than the external ones, + * as long as the result will fit into the external variable size. + */ + uint64_t numSum[3] = {0, 1, 0}, denomSum[3] = {1, 0, 0}; + uint64_t aux, bigNum, bigDenom; + uint64_t returnLimit; + int i; + uint64_t nMax; + double fMax; + unsigned long maxDenom; + /*-- nMax and fMax defines the initial accuracy of the starting fractional, + * or better, the highest used integer numbers used within the starting + * fractional (bigNum/bigDenom). There are two approaches, which can + * accidentally lead to different accuracies just depending on the value. + * Therefore, blnUseSmallRange steers this behavior. + * For long long nMax = ((9223372036854775807-1)/2); for long nMax = + * ((2147483647-1)/2); + */ + if (blnUseSmallRange) + { + nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */ + } + else + { + nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */ + } + fMax = (double)nMax; + + /*-- For the Euclidean GCD define the denominator range, so that it stays + * within size of unsigned long variables. maxDenom should be LONG_MAX for + * negative values and ULONG_MAX for positive ones. Also the final returned + * value of ullNum and ullDenom is limited according to signed- or + * unsigned-range. + */ + if (blnUseSignedRange) + { + maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/ + returnLimit = maxDenom; + } + else + { + maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/ + returnLimit = maxDenom; + } + + /*-- First generate a rational fraction (bigNum/bigDenom) which represents + *the value as a rational number with the highest accuracy. Therefore, + *uint64_t (uint64_t) is needed. This rational fraction is then reduced + *using the Euclidean algorithm to find the greatest common divisor (GCD). + * bigNum = big numinator of value without fraction (or cut residual + *fraction) bigDenom = big denominator of value + *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error + *and bigDenom has no overflow, and stop with enlargement of fraction when + *the double-value of it reaches an integer number without fractional part. + */ + bigDenom = 1; + while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax)) + { + bigDenom <<= 1; + value *= 2; + } + bigNum = (uint64_t)value; + + /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) -- + */ #define MAX_ITERATIONS 64 - for (i = 0; i < MAX_ITERATIONS; i++) { - uint64_t val; - /* if bigDenom is not zero, calculate integer part of fraction. */ - if (bigDenom == 0) { - break; - } - val = bigNum / bigDenom; - - /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous denominator bigDenom. */ - aux = bigNum; - bigNum = bigDenom; - bigDenom = aux % bigDenom; - - /* calculate next denominator and check for its given maximum */ - aux = val; - if (denomSum[1] * val + denomSum[0] >= maxDenom) { - aux = (maxDenom - denomSum[0]) / denomSum[1]; - if (aux * 2 >= val || denomSum[1] >= maxDenom) - i = (MAX_ITERATIONS + 1); /* exit but execute rest of for-loop */ - else - break; - } - /* calculate next numerator to numSum2 and save previous one to numSum0; numSum1 just copy of numSum2. */ - numSum[2] = aux * numSum[1] + numSum[0]; - numSum[0] = numSum[1]; - numSum[1] = numSum[2]; - /* calculate next denominator to denomSum2 and save previous one to denomSum0; denomSum1 just copy of denomSum2. */ - denomSum[2] = aux * denomSum[1] + denomSum[0]; - denomSum[0] = denomSum[1]; - denomSum[1] = denomSum[2]; - } - - /*-- Check and adapt for final variable size and return values; reduces internal accuracy; denominator is kept in ULONG-range with maxDenom -- */ - while (numSum[1] > returnLimit || denomSum[1] > returnLimit) { - numSum[1] = numSum[1] / 2; - denomSum[1] = denomSum[1] / 2; - } - - /* return values */ - *ullNum = numSum[1]; - *ullDenom = denomSum[1]; - -} /*-- ToRationalEuclideanGCD() -------------- */ + for (i = 0; i < MAX_ITERATIONS; i++) + { + uint64_t val; + /* if bigDenom is not zero, calculate integer part of fraction. */ + if (bigDenom == 0) + { + break; + } + val = bigNum / bigDenom; + /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous + * denominator bigDenom. */ + aux = bigNum; + bigNum = bigDenom; + bigDenom = aux % bigDenom; + + /* calculate next denominator and check for its given maximum */ + aux = val; + if (denomSum[1] * val + denomSum[0] >= maxDenom) + { + aux = (maxDenom - denomSum[0]) / denomSum[1]; + if (aux * 2 >= val || denomSum[1] >= maxDenom) + i = (MAX_ITERATIONS + + 1); /* exit but execute rest of for-loop */ + else + break; + } + /* calculate next numerator to numSum2 and save previous one to numSum0; + * numSum1 just copy of numSum2. */ + numSum[2] = aux * numSum[1] + numSum[0]; + numSum[0] = numSum[1]; + numSum[1] = numSum[2]; + /* calculate next denominator to denomSum2 and save previous one to + * denomSum0; denomSum1 just copy of denomSum2. */ + denomSum[2] = aux * denomSum[1] + denomSum[0]; + denomSum[0] = denomSum[1]; + denomSum[1] = denomSum[2]; + } + + /*-- Check and adapt for final variable size and return values; reduces + * internal accuracy; denominator is kept in ULONG-range with maxDenom -- */ + while (numSum[1] > returnLimit || denomSum[1] > returnLimit) + { + numSum[1] = numSum[1] / 2; + denomSum[1] = denomSum[1] / 2; + } + + /* return values */ + *ullNum = numSum[1]; + *ullDenom = denomSum[1]; + +} /*-- ToRationalEuclideanGCD() -------------- */ /**---- DoubleToRational() ----------------------------------------------- * Calculates the rational fractional of a double input value * for UN-SIGNED rationals, * using the Euclidean algorithm to find the greatest common divisor (GCD) ------------------------------------------------------------------------*/ -static -void DoubleToRational(double value, uint32_t *num, uint32_t *denom) -{ - /*---- UN-SIGNED RATIONAL ---- */ - double dblDiff, dblDiff2; - uint64_t ullNum, ullDenom, ullNum2, ullDenom2; - - /*-- Check for negative values. If so it is an error. */ - /* Test written that way to catch NaN */ - if (!(value >= 0)) { - *num = *denom = 0; - TIFFErrorExt(0, "TIFFLib: DoubleToRational()", " Negative Value for Unsigned Rational given."); - return; - } - - /*-- Check for too big numbers (> ULONG_MAX) -- */ - if (value > 0xFFFFFFFFUL) { - *num = 0xFFFFFFFFU; - *denom = 0; - return; - } - /*-- Check for easy integer numbers -- */ - if (value == (uint32_t)(value)) { - *num = (uint32_t)value; - *denom = 1; - return; - } - /*-- Check for too small numbers for "unsigned long" type rationals -- */ - if (value < 1.0 / (double)0xFFFFFFFFUL) { - *num = 0; - *denom = 0xFFFFFFFFU; - return; - } - - /*-- There are two approaches using the Euclidean algorithm, - * which can accidentally lead to different accuracies just depending on the value. - * Try both and define which one was better. - */ - ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom); - ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2); - /*-- Double-Check, that returned values fit into ULONG :*/ - if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL || ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL) { - TIFFErrorExt(0, "TIFFLib: DoubleToRational()", " Num or Denom exceeds ULONG: val=%14.6f, num=%12"PRIu64", denom=%12"PRIu64" | num2=%12"PRIu64", denom2=%12"PRIu64"", value, ullNum, ullDenom, ullNum2, ullDenom2); - assert(0); - } - - /* Check, which one has higher accuracy and take that. */ - dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); - dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); - if (dblDiff < dblDiff2) { - *num = (uint32_t)ullNum; - *denom = (uint32_t)ullDenom; - } - else { - *num = (uint32_t)ullNum2; - *denom = (uint32_t)ullDenom2; - } -} /*-- DoubleToRational() -------------- */ +static void DoubleToRational(double value, uint32_t *num, uint32_t *denom) +{ + /*---- UN-SIGNED RATIONAL ---- */ + double dblDiff, dblDiff2; + uint64_t ullNum, ullDenom, ullNum2, ullDenom2; + + /*-- Check for negative values. If so it is an error. */ + /* Test written that way to catch NaN */ + if (!(value >= 0)) + { + *num = *denom = 0; + TIFFErrorExt(0, "TIFFLib: DoubleToRational()", + " Negative Value for Unsigned Rational given."); + return; + } + + /*-- Check for too big numbers (> ULONG_MAX) -- */ + if (value > 0xFFFFFFFFUL) + { + *num = 0xFFFFFFFFU; + *denom = 0; + return; + } + /*-- Check for easy integer numbers -- */ + if (value == (uint32_t)(value)) + { + *num = (uint32_t)value; + *denom = 1; + return; + } + /*-- Check for too small numbers for "unsigned long" type rationals -- */ + if (value < 1.0 / (double)0xFFFFFFFFUL) + { + *num = 0; + *denom = 0xFFFFFFFFU; + return; + } + + /*-- There are two approaches using the Euclidean algorithm, + * which can accidentally lead to different accuracies just depending on + * the value. Try both and define which one was better. + */ + ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom); + ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2); + /*-- Double-Check, that returned values fit into ULONG :*/ + if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL || + ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL) + { + TIFFErrorExt(0, "TIFFLib: DoubleToRational()", + " Num or Denom exceeds ULONG: val=%14.6f, num=%12" PRIu64 + ", denom=%12" PRIu64 " | num2=%12" PRIu64 + ", denom2=%12" PRIu64 "", + value, ullNum, ullDenom, ullNum2, ullDenom2); + assert(0); + } + + /* Check, which one has higher accuracy and take that. */ + dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); + dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); + if (dblDiff < dblDiff2) + { + *num = (uint32_t)ullNum; + *denom = (uint32_t)ullDenom; + } + else + { + *num = (uint32_t)ullNum2; + *denom = (uint32_t)ullDenom2; + } +} /*-- DoubleToRational() -------------- */ /**---- DoubleToSrational() ----------------------------------------------- * Calculates the rational fractional of a double input value * for SIGNED rationals, * using the Euclidean algorithm to find the greatest common divisor (GCD) ------------------------------------------------------------------------*/ -static -void DoubleToSrational(double value, int32_t *num, int32_t *denom) -{ - /*---- SIGNED RATIONAL ----*/ - int neg = 1; - double dblDiff, dblDiff2; - uint64_t ullNum, ullDenom, ullNum2, ullDenom2; - - /*-- Check for negative values and use then the positive one for internal calculations, but take the sign into account before returning. */ - if (value < 0) { neg = -1; value = -value; } - - /*-- Check for too big numbers (> LONG_MAX) -- */ - if (value > 0x7FFFFFFFL) { - *num = 0x7FFFFFFFL; - *denom = 0; - return; - } - /*-- Check for easy numbers -- */ - if (value == (int32_t)(value)) { - *num = (int32_t)(neg * value); - *denom = 1; - return; - } - /*-- Check for too small numbers for "long" type rationals -- */ - if (value < 1.0 / (double)0x7FFFFFFFL) { - *num = 0; - *denom = 0x7FFFFFFFL; - return; - } - - /*-- There are two approaches using the Euclidean algorithm, - * which can accidentally lead to different accuracies just depending on the value. - * Try both and define which one was better. - * Furthermore, set behavior of ToRationalEuclideanGCD() to the range of signed-long. - */ - ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom); - ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2); - /*-- Double-Check, that returned values fit into LONG :*/ - if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL || ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL) { - TIFFErrorExt(0, "TIFFLib: DoubleToSrational()", " Num or Denom exceeds LONG: val=%14.6f, num=%12"PRIu64", denom=%12"PRIu64" | num2=%12"PRIu64", denom2=%12"PRIu64"", neg*value, ullNum, ullDenom, ullNum2, ullDenom2); - assert(0); - } - - /* Check, which one has higher accuracy and take that. */ - dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); - dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); - if (dblDiff < dblDiff2) { - *num = (int32_t)(neg * (long)ullNum); - *denom = (int32_t)ullDenom; - } - else { - *num = (int32_t)(neg * (long)ullNum2); - *denom = (int32_t)ullDenom2; - } -} /*-- DoubleToSrational() --------------*/ - -static int -TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value) +static void DoubleToSrational(double value, int32_t *num, int32_t *denom) { - assert(count<0x40000000); - assert(sizeof(float)==4); - TIFFCvtNativeToIEEEFloat(tif,count,&value); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfFloat(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value)); -} + /*---- SIGNED RATIONAL ----*/ + int neg = 1; + double dblDiff, dblDiff2; + uint64_t ullNum, ullDenom, ullNum2, ullDenom2; -static int -TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value) -{ - assert(count<0x20000000); - assert(sizeof(double)==8); - TIFFCvtNativeToIEEEDouble(tif,count,&value); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfDouble(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value)); -} + /*-- Check for negative values and use then the positive one for internal + * calculations, but take the sign into account before returning. */ + if (value < 0) + { + neg = -1; + value = -value; + } -static int -TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value) -{ - assert(count<0x40000000); - assert(sizeof(uint32_t) == 4); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value)); -} + /*-- Check for too big numbers (> LONG_MAX) -- */ + if (value > 0x7FFFFFFFL) + { + *num = 0x7FFFFFFFL; + *denom = 0; + return; + } + /*-- Check for easy numbers -- */ + if (value == (int32_t)(value)) + { + *num = (int32_t)(neg * value); + *denom = 1; + return; + } + /*-- Check for too small numbers for "long" type rationals -- */ + if (value < 1.0 / (double)0x7FFFFFFFL) + { + *num = 0; + *denom = 0x7FFFFFFFL; + return; + } -static int -TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value) -{ - assert(count<0x20000000); - assert(sizeof(uint64_t) == 8); - assert(tif->tif_flags&TIFF_BIGTIFF); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabArrayOfLong8(value,count); - return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value)); -} + /*-- There are two approaches using the Euclidean algorithm, + * which can accidentally lead to different accuracies just depending on + * the value. Try both and define which one was better. Furthermore, set + * behavior of ToRationalEuclideanGCD() to the range of signed-long. + */ + ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom); + ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2); + /*-- Double-Check, that returned values fit into LONG :*/ + if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL || + ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL) + { + TIFFErrorExt(0, "TIFFLib: DoubleToSrational()", + " Num or Denom exceeds LONG: val=%14.6f, num=%12" PRIu64 + ", denom=%12" PRIu64 " | num2=%12" PRIu64 + ", denom2=%12" PRIu64 "", + neg * value, ullNum, ullDenom, ullNum2, ullDenom2); + assert(0); + } -static int -TIFFWriteDirectoryTagData(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t datatype, uint32_t count, uint32_t datalength, void* data) -{ - static const char module[] = "TIFFWriteDirectoryTagData"; - uint32_t m; - m=0; - while (m<(*ndir)) - { - assert(dir[m].tdir_tag!=tag); - if (dir[m].tdir_tag>tag) - break; - m++; - } - if (m<(*ndir)) - { - uint32_t n; - for (n=*ndir; n>m; n--) - dir[n]=dir[n-1]; - } - dir[m].tdir_tag=tag; - dir[m].tdir_type=datatype; - dir[m].tdir_count=count; - dir[m].tdir_offset.toff_long8 = 0; - if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U)) + /* Check, which one has higher accuracy and take that. */ + dblDiff = fabs(value - ((double)ullNum / (double)ullDenom)); + dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2)); + if (dblDiff < dblDiff2) + { + *num = (int32_t)(neg * (long)ullNum); + *denom = (int32_t)ullDenom; + } + else + { + *num = (int32_t)(neg * (long)ullNum2); + *denom = (int32_t)ullDenom2; + } +} /*-- DoubleToSrational() --------------*/ + +static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + float *value) +{ + assert(count < 0x40000000); + assert(sizeof(float) == 4); + TIFFCvtNativeToIEEEFloat(tif, count, &value); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfFloat(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count, + count * 4, value)); +} + +static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + double *value) +{ + assert(count < 0x20000000); + assert(sizeof(double) == 8); + TIFFCvtNativeToIEEEDouble(tif, count, &value); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfDouble(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count, + count * 8, value)); +} + +static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint32_t count, uint32_t *value) +{ + assert(count < 0x40000000); + assert(sizeof(uint32_t) == 4); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD, count, + count * 4, value)); +} + +static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, + uint16_t tag, uint32_t count, + uint64_t *value) +{ + assert(count < 0x20000000); + assert(sizeof(uint64_t) == 8); + assert(tif->tif_flags & TIFF_BIGTIFF); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfLong8(value, count); + return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD8, count, + count * 8, value)); +} + +static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir, + TIFFDirEntry *dir, uint16_t tag, + uint16_t datatype, uint32_t count, + uint32_t datalength, void *data) +{ + static const char module[] = "TIFFWriteDirectoryTagData"; + uint32_t m; + m = 0; + while (m < (*ndir)) + { + assert(dir[m].tdir_tag != tag); + if (dir[m].tdir_tag > tag) + break; + m++; + } + if (m < (*ndir)) + { + uint32_t n; + for (n = *ndir; n > m; n--) + dir[n] = dir[n - 1]; + } + dir[m].tdir_tag = tag; + dir[m].tdir_type = datatype; + dir[m].tdir_count = count; + dir[m].tdir_offset.toff_long8 = 0; + if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U)) + { + if (data && datalength) { - if( data && datalength ) - { - _TIFFmemcpy(&dir[m].tdir_offset,data,datalength); - } + _TIFFmemcpy(&dir[m].tdir_offset, data, datalength); + } + } + else + { + uint64_t na, nb; + na = tif->tif_dataoff; + nb = na + datalength; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + nb = (uint32_t)nb; + if ((nb < na) || (nb < datalength)) + { + TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); + return (0); + } + if (!SeekOK(tif, na)) + { + TIFFErrorExtR(tif, module, "IO error writing tag data"); + return (0); + } + if (datalength >= 0x80000000UL) + { + TIFFErrorExtR(tif, module, + "libtiff does not allow writing more than 2147483647 " + "bytes in a tag"); + return (0); + } + if (!WriteOK(tif, data, (tmsize_t)datalength)) + { + TIFFErrorExtR(tif, module, "IO error writing tag data"); + return (0); + } + tif->tif_dataoff = nb; + if (tif->tif_dataoff & 1) + tif->tif_dataoff++; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t o; + o = (uint32_t)na; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&o); + _TIFFmemcpy(&dir[m].tdir_offset, &o, 4); } - else - { - uint64_t na,nb; - na=tif->tif_dataoff; - nb=na+datalength; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - nb=(uint32_t)nb; - if ((nb<na)||(nb<datalength)) - { - TIFFErrorExtR(tif,module,"Maximum TIFF file size exceeded"); - return(0); - } - if (!SeekOK(tif,na)) - { - TIFFErrorExtR(tif,module,"IO error writing tag data"); - return(0); - } - if (datalength >= 0x80000000UL) - { - TIFFErrorExtR(tif,module, - "libtiff does not allow writing more than 2147483647 bytes in a tag"); - return(0); - } - if (!WriteOK(tif,data,(tmsize_t)datalength)) - { - TIFFErrorExtR(tif,module,"IO error writing tag data"); - return(0); - } - tif->tif_dataoff=nb; - if (tif->tif_dataoff&1) - tif->tif_dataoff++; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32_t o; - o=(uint32_t)na; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong(&o); - _TIFFmemcpy(&dir[m].tdir_offset,&o,4); - } - else - { - dir[m].tdir_offset.toff_long8 = na; - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8(&dir[m].tdir_offset.toff_long8); - } - } - (*ndir)++; - return(1); + else + { + dir[m].tdir_offset.toff_long8 = na; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dir[m].tdir_offset.toff_long8); + } + } + (*ndir)++; + return (1); } /* * Link the current directory into the directory chain for the file. */ -static int -TIFFLinkDirectory(TIFF* tif) -{ - static const char module[] = "TIFFLinkDirectory"; - - tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) & (~((toff_t)1)); - - /* - * Handle SubIFDs - */ - if (tif->tif_flags & TIFF_INSUBIFD) - { - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32_t m; - m = (uint32_t)tif->tif_diroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&m); - (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); - if (!WriteOK(tif, &m, 4)) { - TIFFErrorExtR(tif, module, - "Error writing SubIFD directory link"); - return (0); - } - /* - * Advance to the next SubIFD or, if this is - * the last one configured, revert back to the - * normal directory linkage. - */ - if (--tif->tif_nsubifd) - tif->tif_subifdoff += 4; - else - tif->tif_flags &= ~TIFF_INSUBIFD; - return (1); - } - else - { - uint64_t m; - m = tif->tif_diroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&m); - (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); - if (!WriteOK(tif, &m, 8)) { - TIFFErrorExtR(tif, module, - "Error writing SubIFD directory link"); - return (0); - } - /* - * Advance to the next SubIFD or, if this is - * the last one configured, revert back to the - * normal directory linkage. - */ - if (--tif->tif_nsubifd) - tif->tif_subifdoff += 8; - else - tif->tif_flags &= ~TIFF_INSUBIFD; - return (1); - } - } - - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - uint32_t m; - uint32_t nextdir; - m = (uint32_t)(tif->tif_diroff); - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&m); - if (tif->tif_header.classic.tiff_diroff == 0) { - /* - * First directory, overwrite offset in header. - */ - tif->tif_header.classic.tiff_diroff = (uint32_t) tif->tif_diroff; - tif->tif_lastdiroff = tif->tif_diroff; - (void) TIFFSeekFile(tif,4, SEEK_SET); - if (!WriteOK(tif, &m, 4)) { - TIFFErrorExtR(tif, tif->tif_name, - "Error writing TIFF header"); - return (0); - } - return (1); - } - /* - * Not the first directory, search to the last and append. - */ - if (tif->tif_lastdiroff != 0) { - nextdir = (uint32_t) tif->tif_lastdiroff; - } - else { - nextdir = tif->tif_header.classic.tiff_diroff; - } - - while(1) { - uint16_t dircount; - uint32_t nextnextdir; - - if (!SeekOK(tif, nextdir) || - !ReadOK(tif, &dircount, 2)) { - TIFFErrorExtR(tif, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&dircount); - (void) TIFFSeekFile(tif, - nextdir+2+dircount*12, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 4)) { - TIFFErrorExtR(tif, module, - "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&nextnextdir); - if (nextnextdir==0) - { - (void) TIFFSeekFile(tif, - nextdir+2+dircount*12, SEEK_SET); - if (!WriteOK(tif, &m, 4)) { - TIFFErrorExtR(tif, module, - "Error writing directory link"); - return (0); - } - tif->tif_lastdiroff = tif->tif_diroff; - break; - } - nextdir=nextnextdir; - } - } - else - { - uint64_t m; - uint64_t nextdir; - m = tif->tif_diroff; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&m); - if (tif->tif_header.big.tiff_diroff == 0) { - /* - * First directory, overwrite offset in header. - */ - tif->tif_header.big.tiff_diroff = tif->tif_diroff; - tif->tif_lastdiroff = tif->tif_diroff; - (void) TIFFSeekFile(tif,8, SEEK_SET); - if (!WriteOK(tif, &m, 8)) { - TIFFErrorExtR(tif, tif->tif_name, - "Error writing TIFF header"); - return (0); - } - return (1); - } - /* - * Not the first directory, search to the last and append. - */ - if (tif->tif_lastdiroff != 0) { - nextdir = tif->tif_lastdiroff; - } - else { - nextdir = tif->tif_header.big.tiff_diroff; - } - while(1) { - uint64_t dircount64; - uint16_t dircount; - uint64_t nextnextdir; - - if (!SeekOK(tif, nextdir) || - !ReadOK(tif, &dircount64, 8)) { - TIFFErrorExtR(tif, module, - "Error fetching directory count"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&dircount64); - if (dircount64>0xFFFF) - { - TIFFErrorExtR(tif, module, - "Sanity check on tag count failed, likely corrupt TIFF"); - return (0); - } - dircount=(uint16_t)dircount64; - (void) TIFFSeekFile(tif, - nextdir+8+dircount*20, SEEK_SET); - if (!ReadOK(tif, &nextnextdir, 8)) { - TIFFErrorExtR(tif, module, - "Error fetching directory link"); - return (0); - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong8(&nextnextdir); - if (nextnextdir==0) - { - (void) TIFFSeekFile(tif, - nextdir+8+dircount*20, SEEK_SET); - if (!WriteOK(tif, &m, 8)) { - TIFFErrorExtR(tif, module, - "Error writing directory link"); - return (0); - } - tif->tif_lastdiroff = tif->tif_diroff; - break; - } - nextdir=nextnextdir; - } - } - return (1); +static int TIFFLinkDirectory(TIFF *tif) +{ + static const char module[] = "TIFFLinkDirectory"; + + tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1)); + + /* + * Handle SubIFDs + */ + if (tif->tif_flags & TIFF_INSUBIFD) + { + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t m; + m = (uint32_t)tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&m); + (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); + if (!WriteOK(tif, &m, 4)) + { + TIFFErrorExtR(tif, module, + "Error writing SubIFD directory link"); + return (0); + } + /* + * Advance to the next SubIFD or, if this is + * the last one configured, revert back to the + * normal directory linkage. + */ + if (--tif->tif_nsubifd) + tif->tif_subifdoff += 4; + else + tif->tif_flags &= ~TIFF_INSUBIFD; + return (1); + } + else + { + uint64_t m; + m = tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&m); + (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); + if (!WriteOK(tif, &m, 8)) + { + TIFFErrorExtR(tif, module, + "Error writing SubIFD directory link"); + return (0); + } + /* + * Advance to the next SubIFD or, if this is + * the last one configured, revert back to the + * normal directory linkage. + */ + if (--tif->tif_nsubifd) + tif->tif_subifdoff += 8; + else + tif->tif_flags &= ~TIFF_INSUBIFD; + return (1); + } + } + + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + uint32_t m; + uint32_t nextdir; + m = (uint32_t)(tif->tif_diroff); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&m); + if (tif->tif_header.classic.tiff_diroff == 0) + { + /* + * First directory, overwrite offset in header. + */ + tif->tif_header.classic.tiff_diroff = (uint32_t)tif->tif_diroff; + tif->tif_lastdiroff = tif->tif_diroff; + (void)TIFFSeekFile(tif, 4, SEEK_SET); + if (!WriteOK(tif, &m, 4)) + { + TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header"); + return (0); + } + return (1); + } + /* + * Not the first directory, search to the last and append. + */ + if (tif->tif_lastdiroff != 0) + { + nextdir = (uint32_t)tif->tif_lastdiroff; + } + else + { + nextdir = tif->tif_header.classic.tiff_diroff; + } + + while (1) + { + uint16_t dircount; + uint32_t nextnextdir; + + if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2)) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&dircount); + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 4)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&nextnextdir); + if (nextnextdir == 0) + { + (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET); + if (!WriteOK(tif, &m, 4)) + { + TIFFErrorExtR(tif, module, "Error writing directory link"); + return (0); + } + tif->tif_lastdiroff = tif->tif_diroff; + break; + } + nextdir = nextnextdir; + } + } + else + { + uint64_t m; + uint64_t nextdir; + m = tif->tif_diroff; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&m); + if (tif->tif_header.big.tiff_diroff == 0) + { + /* + * First directory, overwrite offset in header. + */ + tif->tif_header.big.tiff_diroff = tif->tif_diroff; + tif->tif_lastdiroff = tif->tif_diroff; + (void)TIFFSeekFile(tif, 8, SEEK_SET); + if (!WriteOK(tif, &m, 8)) + { + TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header"); + return (0); + } + return (1); + } + /* + * Not the first directory, search to the last and append. + */ + if (tif->tif_lastdiroff != 0) + { + nextdir = tif->tif_lastdiroff; + } + else + { + nextdir = tif->tif_header.big.tiff_diroff; + } + while (1) + { + uint64_t dircount64; + uint16_t dircount; + uint64_t nextnextdir; + + if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8)) + { + TIFFErrorExtR(tif, module, "Error fetching directory count"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&dircount64); + if (dircount64 > 0xFFFF) + { + TIFFErrorExtR( + tif, module, + "Sanity check on tag count failed, likely corrupt TIFF"); + return (0); + } + dircount = (uint16_t)dircount64; + (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); + if (!ReadOK(tif, &nextnextdir, 8)) + { + TIFFErrorExtR(tif, module, "Error fetching directory link"); + return (0); + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&nextnextdir); + if (nextnextdir == 0) + { + (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET); + if (!WriteOK(tif, &m, 8)) + { + TIFFErrorExtR(tif, module, "Error writing directory link"); + return (0); + } + tif->tif_lastdiroff = tif->tif_diroff; + break; + } + nextdir = nextnextdir; + } + } + return (1); } /************************************************************************/ @@ -2661,9 +3153,8 @@ TIFFLinkDirectory(TIFF* tif) /* Returns zero on failure, and one on success. */ /************************************************************************/ -int -_TIFFRewriteField(TIFF* tif, uint16_t tag, TIFFDataType in_datatype, - tmsize_t count, void* data) +int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype, + tmsize_t count, void *data) { static const char module[] = "TIFFResetField"; /* const TIFFField* fip = NULL; */ @@ -2674,63 +3165,67 @@ _TIFFRewriteField(TIFF* tif, uint16_t tag, TIFFDataType in_datatype, uint16_t entry_type = 0; uint64_t entry_count = 0; uint64_t entry_offset = 0; - int value_in_entry = 0; + int value_in_entry = 0; uint64_t read_offset; uint8_t *buf_to_write = NULL; TIFFDataType datatype; -/* -------------------------------------------------------------------- */ -/* Find field definition. */ -/* -------------------------------------------------------------------- */ - /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY); + /* -------------------------------------------------------------------- */ + /* Find field definition. */ + /* -------------------------------------------------------------------- */ + /*fip =*/TIFFFindField(tif, tag, TIFF_ANY); -/* -------------------------------------------------------------------- */ -/* Do some checking this is a straight forward case. */ -/* -------------------------------------------------------------------- */ - if( isMapped(tif) ) + /* -------------------------------------------------------------------- */ + /* Do some checking this is a straight forward case. */ + /* -------------------------------------------------------------------- */ + if (isMapped(tif)) { - TIFFErrorExtR(tif, module, - "Memory mapped files not currently supported for this operation." ); + TIFFErrorExtR( + tif, module, + "Memory mapped files not currently supported for this operation."); return 0; } - if( tif->tif_diroff == 0 ) + if (tif->tif_diroff == 0) { - TIFFErrorExtR(tif, module, - "Attempt to reset field on directory not already on disk." ); + TIFFErrorExtR( + tif, module, + "Attempt to reset field on directory not already on disk."); return 0; } -/* -------------------------------------------------------------------- */ -/* Read the directory entry count. */ -/* -------------------------------------------------------------------- */ - if (!SeekOK(tif, tif->tif_diroff)) { - TIFFErrorExtR(tif, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); + /* -------------------------------------------------------------------- */ + /* Read the directory entry count. */ + /* -------------------------------------------------------------------- */ + if (!SeekOK(tif, tif->tif_diroff)) + { + TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory", + tif->tif_name); return 0; } read_offset = tif->tif_diroff; - if (!(tif->tif_flags&TIFF_BIGTIFF)) + if (!(tif->tif_flags & TIFF_BIGTIFF)) { - if (!ReadOK(tif, &dircount, sizeof (uint16_t))) { - TIFFErrorExtR(tif, module, - "%s: Can not read TIFF directory count", - tif->tif_name); + if (!ReadOK(tif, &dircount, sizeof(uint16_t))) + { + TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count", + tif->tif_name); return 0; } if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount); dirsize = 12; read_offset += 2; - } else { + } + else + { uint64_t dircount64; - if (!ReadOK(tif, &dircount64, sizeof (uint64_t))) { - TIFFErrorExtR(tif, module, - "%s: Can not read TIFF directory count", - tif->tif_name); + if (!ReadOK(tif, &dircount64, sizeof(uint64_t))) + { + TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count", + tif->tif_name); return 0; } if (tif->tif_flags & TIFF_SWAB) @@ -2740,104 +3235,104 @@ _TIFFRewriteField(TIFF* tif, uint16_t tag, TIFFDataType in_datatype, read_offset += 8; } -/* -------------------------------------------------------------------- */ -/* Read through directory to find target tag. */ -/* -------------------------------------------------------------------- */ - while( dircount > 0 ) + /* -------------------------------------------------------------------- */ + /* Read through directory to find target tag. */ + /* -------------------------------------------------------------------- */ + while (dircount > 0) { - if (!ReadOK(tif, direntry_raw, dirsize)) { - TIFFErrorExtR(tif, module, - "%s: Can not read TIFF directory entry.", - tif->tif_name); + if (!ReadOK(tif, direntry_raw, dirsize)) + { + TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory entry.", + tif->tif_name); return 0; } - memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort( &entry_tag ); + memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&entry_tag); - if( entry_tag == tag ) + if (entry_tag == tag) break; read_offset += dirsize; } - if( entry_tag != tag ) + if (entry_tag != tag) { - TIFFErrorExtR(tif, module, - "%s: Could not find tag %"PRIu16".", - tif->tif_name, tag ); + TIFFErrorExtR(tif, module, "%s: Could not find tag %" PRIu16 ".", + tif->tif_name, tag); return 0; } -/* -------------------------------------------------------------------- */ -/* Extract the type, count and offset for this entry. */ -/* -------------------------------------------------------------------- */ - memcpy( &entry_type, direntry_raw + 2, sizeof(uint16_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort( &entry_type ); + /* -------------------------------------------------------------------- */ + /* Extract the type, count and offset for this entry. */ + /* -------------------------------------------------------------------- */ + memcpy(&entry_type, direntry_raw + 2, sizeof(uint16_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&entry_type); - if (!(tif->tif_flags&TIFF_BIGTIFF)) + if (!(tif->tif_flags & TIFF_BIGTIFF)) { uint32_t value; - - memcpy( &value, direntry_raw + 4, sizeof(uint32_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong( &value ); + + memcpy(&value, direntry_raw + 4, sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&value); entry_count = value; - memcpy( &value, direntry_raw + 8, sizeof(uint32_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong( &value ); + memcpy(&value, direntry_raw + 8, sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&value); entry_offset = value; } else { - memcpy( &entry_count, direntry_raw + 4, sizeof(uint64_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8( &entry_count ); + memcpy(&entry_count, direntry_raw + 4, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&entry_count); - memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8( &entry_offset ); + memcpy(&entry_offset, direntry_raw + 12, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8(&entry_offset); } -/* -------------------------------------------------------------------- */ -/* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */ -/* -------------------------------------------------------------------- */ - if( entry_offset == 0 && entry_count == 0 && entry_type == 0 ) + /* -------------------------------------------------------------------- */ + /* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */ + /* -------------------------------------------------------------------- */ + if (entry_offset == 0 && entry_count == 0 && entry_type == 0) { - if( tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS ) + if (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) { - entry_type = (tif->tif_flags&TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG; + entry_type = + (tif->tif_flags & TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG; } else { int write_aslong8 = 1; - if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS ) + if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) { write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif)); } - else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS ) + else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) { write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif)); } - if( write_aslong8 ) + if (write_aslong8) { entry_type = TIFF_LONG8; } else { int write_aslong4 = 1; - if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS ) + if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS) { write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif)); } - else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS ) + else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS) { write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif)); } - if( write_aslong4 ) + if (write_aslong4) { entry_type = TIFF_LONG; } @@ -2849,123 +3344,120 @@ _TIFFRewriteField(TIFF* tif, uint16_t tag, TIFFDataType in_datatype, } } -/* -------------------------------------------------------------------- */ -/* What data type do we want to write this as? */ -/* -------------------------------------------------------------------- */ - if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) ) + /* -------------------------------------------------------------------- */ + /* What data type do we want to write this as? */ + /* -------------------------------------------------------------------- */ + if (TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags & TIFF_BIGTIFF)) { - if( in_datatype == TIFF_LONG8 ) + if (in_datatype == TIFF_LONG8) datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG; - else if( in_datatype == TIFF_SLONG8 ) + else if (in_datatype == TIFF_SLONG8) datatype = TIFF_SLONG; - else if( in_datatype == TIFF_IFD8 ) + else if (in_datatype == TIFF_IFD8) datatype = TIFF_IFD; else datatype = in_datatype; } else { - if( in_datatype == TIFF_LONG8 && + if (in_datatype == TIFF_LONG8 && (entry_type == TIFF_SHORT || entry_type == TIFF_LONG || - entry_type == TIFF_LONG8 ) ) + entry_type == TIFF_LONG8)) datatype = entry_type; - else if( in_datatype == TIFF_SLONG8 && - (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8 ) ) + else if (in_datatype == TIFF_SLONG8 && + (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8)) datatype = entry_type; - else if( in_datatype == TIFF_IFD8 && - (entry_type == TIFF_IFD || entry_type == TIFF_IFD8 ) ) + else if (in_datatype == TIFF_IFD8 && + (entry_type == TIFF_IFD || entry_type == TIFF_IFD8)) datatype = entry_type; else datatype = in_datatype; } -/* -------------------------------------------------------------------- */ -/* Prepare buffer of actual data to write. This includes */ -/* swabbing as needed. */ -/* -------------------------------------------------------------------- */ - buf_to_write = - (uint8_t *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype), - "for field buffer."); + /* -------------------------------------------------------------------- */ + /* Prepare buffer of actual data to write. This includes */ + /* swabbing as needed. */ + /* -------------------------------------------------------------------- */ + buf_to_write = (uint8_t *)_TIFFCheckMalloc( + tif, count, TIFFDataWidth(datatype), "for field buffer."); if (!buf_to_write) return 0; - if( datatype == in_datatype ) - memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) ); - else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 ) + if (datatype == in_datatype) + memcpy(buf_to_write, data, count * TIFFDataWidth(datatype)); + else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8) { - tmsize_t i; + tmsize_t i; - for( i = 0; i < count; i++ ) + for (i = 0; i < count; i++) { - ((int32_t *) buf_to_write)[i] = - (int32_t) ((int64_t *) data)[i]; - if((int64_t) ((int32_t *) buf_to_write)[i] != ((int64_t *) data)[i] ) + ((int32_t *)buf_to_write)[i] = (int32_t)((int64_t *)data)[i]; + if ((int64_t)((int32_t *)buf_to_write)[i] != ((int64_t *)data)[i]) { - _TIFFfreeExt(tif, buf_to_write ); + _TIFFfreeExt(tif, buf_to_write); TIFFErrorExtR(tif, module, - "Value exceeds 32bit range of output type." ); + "Value exceeds 32bit range of output type."); return 0; } } } - else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8) - || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) ) + else if ((datatype == TIFF_LONG && in_datatype == TIFF_LONG8) || + (datatype == TIFF_IFD && in_datatype == TIFF_IFD8)) { - tmsize_t i; + tmsize_t i; - for( i = 0; i < count; i++ ) + for (i = 0; i < count; i++) { - ((uint32_t *) buf_to_write)[i] = - (uint32_t) ((uint64_t *) data)[i]; - if((uint64_t) ((uint32_t *) buf_to_write)[i] != ((uint64_t *) data)[i] ) + ((uint32_t *)buf_to_write)[i] = (uint32_t)((uint64_t *)data)[i]; + if ((uint64_t)((uint32_t *)buf_to_write)[i] != + ((uint64_t *)data)[i]) { - _TIFFfreeExt(tif, buf_to_write ); + _TIFFfreeExt(tif, buf_to_write); TIFFErrorExtR(tif, module, - "Value exceeds 32bit range of output type." ); + "Value exceeds 32bit range of output type."); return 0; } } } - else if( datatype == TIFF_SHORT && in_datatype == TIFF_LONG8 ) + else if (datatype == TIFF_SHORT && in_datatype == TIFF_LONG8) { - tmsize_t i; + tmsize_t i; - for( i = 0; i < count; i++ ) + for (i = 0; i < count; i++) { - ((uint16_t *) buf_to_write)[i] = - (uint16_t) ((uint64_t *) data)[i]; - if((uint64_t) ((uint16_t *) buf_to_write)[i] != ((uint64_t *) data)[i] ) + ((uint16_t *)buf_to_write)[i] = (uint16_t)((uint64_t *)data)[i]; + if ((uint64_t)((uint16_t *)buf_to_write)[i] != + ((uint64_t *)data)[i]) { - _TIFFfreeExt(tif, buf_to_write ); + _TIFFfreeExt(tif, buf_to_write); TIFFErrorExtR(tif, module, - "Value exceeds 16bit range of output type." ); + "Value exceeds 16bit range of output type."); return 0; } } } else { - TIFFErrorExtR(tif, module, - "Unhandled type conversion." ); + TIFFErrorExtR(tif, module, "Unhandled type conversion."); return 0; } - if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) ) + if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB)) { - if( TIFFDataWidth(datatype) == 2 ) - TIFFSwabArrayOfShort((uint16_t *) buf_to_write, count ); - else if( TIFFDataWidth(datatype) == 4 ) - TIFFSwabArrayOfLong((uint32_t *) buf_to_write, count ); - else if( TIFFDataWidth(datatype) == 8 ) - TIFFSwabArrayOfLong8((uint64_t *) buf_to_write, count ); + if (TIFFDataWidth(datatype) == 2) + TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count); + else if (TIFFDataWidth(datatype) == 4) + TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count); + else if (TIFFDataWidth(datatype) == 8) + TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count); } -/* -------------------------------------------------------------------- */ -/* Is this a value that fits into the directory entry? */ -/* -------------------------------------------------------------------- */ - if (!(tif->tif_flags&TIFF_BIGTIFF)) + /* -------------------------------------------------------------------- */ + /* Is this a value that fits into the directory entry? */ + /* -------------------------------------------------------------------- */ + if (!(tif->tif_flags & TIFF_BIGTIFF)) { - if( TIFFDataWidth(datatype) * count <= 4 ) + if (TIFFDataWidth(datatype) * count <= 4) { entry_offset = read_offset + 8; value_in_entry = 1; @@ -2973,137 +3465,139 @@ _TIFFRewriteField(TIFF* tif, uint16_t tag, TIFFDataType in_datatype, } else { - if( TIFFDataWidth(datatype) * count <= 8 ) + if (TIFFDataWidth(datatype) * count <= 8) { entry_offset = read_offset + 12; value_in_entry = 1; } } - if( (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) && + if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) && tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 ) + tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0) { tif->tif_dir.td_stripoffset_entry.tdir_type = datatype; tif->tif_dir.td_stripoffset_entry.tdir_count = count; } - else if( (tag == TIFFTAG_TILEBYTECOUNTS || tag == TIFFTAG_STRIPBYTECOUNTS) && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 ) + else if ((tag == TIFFTAG_TILEBYTECOUNTS || + tag == TIFFTAG_STRIPBYTECOUNTS) && + tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) { tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype; tif->tif_dir.td_stripbytecount_entry.tdir_count = count; } -/* -------------------------------------------------------------------- */ -/* If the tag type, and count match, then we just write it out */ -/* over the old values without altering the directory entry at */ -/* all. */ -/* -------------------------------------------------------------------- */ - if( entry_count == (uint64_t)count && entry_type == (uint16_t) datatype ) + /* -------------------------------------------------------------------- */ + /* If the tag type, and count match, then we just write it out */ + /* over the old values without altering the directory entry at */ + /* all. */ + /* -------------------------------------------------------------------- */ + if (entry_count == (uint64_t)count && entry_type == (uint16_t)datatype) { - if (!SeekOK(tif, entry_offset)) { - _TIFFfreeExt(tif, buf_to_write ); + if (!SeekOK(tif, entry_offset)) + { + _TIFFfreeExt(tif, buf_to_write); TIFFErrorExtR(tif, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); + "%s: Seek error accessing TIFF directory", + tif->tif_name); return 0; } - if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) { - _TIFFfreeExt(tif, buf_to_write ); - TIFFErrorExtR(tif, module, - "Error writing directory link"); + if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype))) + { + _TIFFfreeExt(tif, buf_to_write); + TIFFErrorExtR(tif, module, "Error writing directory link"); return (0); } - _TIFFfreeExt(tif, buf_to_write ); + _TIFFfreeExt(tif, buf_to_write); return 1; } -/* -------------------------------------------------------------------- */ -/* Otherwise, we write the new tag data at the end of the file. */ -/* -------------------------------------------------------------------- */ - if( !value_in_entry ) + /* -------------------------------------------------------------------- */ + /* Otherwise, we write the new tag data at the end of the file. */ + /* -------------------------------------------------------------------- */ + if (!value_in_entry) { - entry_offset = TIFFSeekFile(tif,0,SEEK_END); - - if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) { - _TIFFfreeExt(tif, buf_to_write ); - TIFFErrorExtR(tif, module, - "Error writing directory link"); + entry_offset = TIFFSeekFile(tif, 0, SEEK_END); + + if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype))) + { + _TIFFfreeExt(tif, buf_to_write); + TIFFErrorExtR(tif, module, "Error writing directory link"); return (0); } } else { - if( count*TIFFDataWidth(datatype) == 4 ) + if (count * TIFFDataWidth(datatype) == 4) { uint32_t value; - memcpy( &value, buf_to_write, count*TIFFDataWidth(datatype)); + memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype)); entry_offset = value; } else { - memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype)); + memcpy(&entry_offset, buf_to_write, + count * TIFFDataWidth(datatype)); } } - _TIFFfreeExt(tif, buf_to_write ); + _TIFFfreeExt(tif, buf_to_write); buf_to_write = 0; -/* -------------------------------------------------------------------- */ -/* Adjust the directory entry. */ -/* -------------------------------------------------------------------- */ + /* -------------------------------------------------------------------- */ + /* Adjust the directory entry. */ + /* -------------------------------------------------------------------- */ entry_type = datatype; entry_count = (uint64_t)count; - memcpy( direntry_raw + 2, &entry_type, sizeof(uint16_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabShort( (uint16_t *) (direntry_raw + 2) ); + memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort((uint16_t *)(direntry_raw + 2)); - if (!(tif->tif_flags&TIFF_BIGTIFF)) + if (!(tif->tif_flags & TIFF_BIGTIFF)) { uint32_t value; - value = (uint32_t) entry_count; - memcpy( direntry_raw + 4, &value, sizeof(uint32_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong( (uint32_t *) (direntry_raw + 4) ); + value = (uint32_t)entry_count; + memcpy(direntry_raw + 4, &value, sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)(direntry_raw + 4)); - value = (uint32_t) entry_offset; - memcpy( direntry_raw + 8, &value, sizeof(uint32_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong( (uint32_t *) (direntry_raw + 8) ); + value = (uint32_t)entry_offset; + memcpy(direntry_raw + 8, &value, sizeof(uint32_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong((uint32_t *)(direntry_raw + 8)); } else { - memcpy( direntry_raw + 4, &entry_count, sizeof(uint64_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8( (uint64_t *) (direntry_raw + 4) ); + memcpy(direntry_raw + 4, &entry_count, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)(direntry_raw + 4)); - memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64_t) ); - if (tif->tif_flags&TIFF_SWAB) - TIFFSwabLong8( (uint64_t *) (direntry_raw + 12) ); + memcpy(direntry_raw + 12, &entry_offset, sizeof(uint64_t)); + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong8((uint64_t *)(direntry_raw + 12)); } -/* -------------------------------------------------------------------- */ -/* Write the directory entry out to disk. */ -/* -------------------------------------------------------------------- */ - if (!SeekOK(tif, read_offset )) { - TIFFErrorExtR(tif, module, - "%s: Seek error accessing TIFF directory", - tif->tif_name); + /* -------------------------------------------------------------------- */ + /* Write the directory entry out to disk. */ + /* -------------------------------------------------------------------- */ + if (!SeekOK(tif, read_offset)) + { + TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory", + tif->tif_name); return 0; } - if (!WriteOK(tif, direntry_raw,dirsize)) + if (!WriteOK(tif, direntry_raw, dirsize)) { - TIFFErrorExtR(tif, module, - "%s: Can not write TIFF directory entry.", - tif->tif_name); + TIFFErrorExtR(tif, module, "%s: Can not write TIFF directory entry.", + tif->tif_name); return 0; } - + return 1; } diff --git a/libtiff/tif_dumpmode.c b/libtiff/tif_dumpmode.c index 7629090a..267d5d2d 100644 --- a/libtiff/tif_dumpmode.c +++ b/libtiff/tif_dumpmode.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,98 +29,94 @@ */ #include "tiffiop.h" -static int -DumpFixupTags(TIFF* tif) +static int DumpFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } /* * Encode a hunk of pixels. */ -static int -DumpModeEncode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s) +static int DumpModeEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) { - (void) s; - while (cc > 0) { - tmsize_t n; + (void)s; + while (cc > 0) + { + tmsize_t n; - n = cc; - if (tif->tif_rawcc + n > tif->tif_rawdatasize) - n = tif->tif_rawdatasize - tif->tif_rawcc; + n = cc; + if (tif->tif_rawcc + n > tif->tif_rawdatasize) + n = tif->tif_rawdatasize - tif->tif_rawcc; - assert( n > 0 ); + assert(n > 0); - /* - * Avoid copy if client has setup raw - * data buffer to avoid extra copy. - */ - if (tif->tif_rawcp != pp) - _TIFFmemcpy(tif->tif_rawcp, pp, n); - tif->tif_rawcp += n; - tif->tif_rawcc += n; - pp += n; - cc -= n; - if (tif->tif_rawcc >= tif->tif_rawdatasize && - !TIFFFlushData1(tif)) - return (0); - } - return (1); + /* + * Avoid copy if client has setup raw + * data buffer to avoid extra copy. + */ + if (tif->tif_rawcp != pp) + _TIFFmemcpy(tif->tif_rawcp, pp, n); + tif->tif_rawcp += n; + tif->tif_rawcc += n; + pp += n; + cc -= n; + if (tif->tif_rawcc >= tif->tif_rawdatasize && !TIFFFlushData1(tif)) + return (0); + } + return (1); } /* * Decode a hunk of pixels. */ -static int -DumpModeDecode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) +static int DumpModeDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - static const char module[] = "DumpModeDecode"; - (void) s; - if (tif->tif_rawcc < cc) { - TIFFErrorExtR(tif, module, -"Not enough data for scanline %"PRIu32", expected a request for at most %"TIFF_SSIZE_FORMAT" bytes, got a request for %"TIFF_SSIZE_FORMAT" bytes", - tif->tif_row, - tif->tif_rawcc, - cc); - return (0); - } - /* - * Avoid copy if client has setup raw - * data buffer to avoid extra copy. - */ - if (tif->tif_rawcp != buf) - _TIFFmemcpy(buf, tif->tif_rawcp, cc); - tif->tif_rawcp += cc; - tif->tif_rawcc -= cc; - return (1); + static const char module[] = "DumpModeDecode"; + (void)s; + if (tif->tif_rawcc < cc) + { + TIFFErrorExtR(tif, module, + "Not enough data for scanline %" PRIu32 + ", expected a request for at most %" TIFF_SSIZE_FORMAT + " bytes, got a request for %" TIFF_SSIZE_FORMAT " bytes", + tif->tif_row, tif->tif_rawcc, cc); + return (0); + } + /* + * Avoid copy if client has setup raw + * data buffer to avoid extra copy. + */ + if (tif->tif_rawcp != buf) + _TIFFmemcpy(buf, tif->tif_rawcp, cc); + tif->tif_rawcp += cc; + tif->tif_rawcc -= cc; + return (1); } /* * Seek forwards nrows in the current strip. */ -static int -DumpModeSeek(TIFF* tif, uint32_t nrows) +static int DumpModeSeek(TIFF *tif, uint32_t nrows) { - tif->tif_rawcp += nrows * tif->tif_scanlinesize; - tif->tif_rawcc -= nrows * tif->tif_scanlinesize; - return (1); + tif->tif_rawcp += nrows * tif->tif_scanlinesize; + tif->tif_rawcc -= nrows * tif->tif_scanlinesize; + return (1); } /* * Initialize dump mode. */ -int -TIFFInitDumpMode(TIFF* tif, int scheme) +int TIFFInitDumpMode(TIFF *tif, int scheme) { - (void) scheme; - tif->tif_fixuptags = DumpFixupTags; - tif->tif_decoderow = DumpModeDecode; - tif->tif_decodestrip = DumpModeDecode; - tif->tif_decodetile = DumpModeDecode; - tif->tif_encoderow = DumpModeEncode; - tif->tif_encodestrip = DumpModeEncode; - tif->tif_encodetile = DumpModeEncode; - tif->tif_seek = DumpModeSeek; - return (1); + (void)scheme; + tif->tif_fixuptags = DumpFixupTags; + tif->tif_decoderow = DumpModeDecode; + tif->tif_decodestrip = DumpModeDecode; + tif->tif_decodetile = DumpModeDecode; + tif->tif_encoderow = DumpModeEncode; + tif->tif_encodestrip = DumpModeEncode; + tif->tif_encodetile = DumpModeEncode; + tif->tif_seek = DumpModeSeek; + return (1); } diff --git a/libtiff/tif_error.c b/libtiff/tif_error.c index f1aa799d..ac0b9c37 100644 --- a/libtiff/tif_error.c +++ b/libtiff/tif_error.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,93 +29,104 @@ TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL; -TIFFErrorHandler -TIFFSetErrorHandler(TIFFErrorHandler handler) +TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler handler) { - TIFFErrorHandler prev = _TIFFerrorHandler; - _TIFFerrorHandler = handler; - return (prev); + TIFFErrorHandler prev = _TIFFerrorHandler; + _TIFFerrorHandler = handler; + return (prev); } -TIFFErrorHandlerExt -TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler) +TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler) { - TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt; - _TIFFerrorHandlerExt = handler; - return (prev); + TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt; + _TIFFerrorHandlerExt = handler; + return (prev); } -void -TIFFError(const char* module, const char* fmt, ...) +void TIFFError(const char *module, const char *fmt, ...) { - va_list ap; - if (_TIFFerrorHandler) { - va_start(ap, fmt); - (*_TIFFerrorHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFerrorHandlerExt) { - va_start(ap, fmt); - (*_TIFFerrorHandlerExt)(0, module, fmt, ap); - va_end(ap); - } + va_list ap; + if (_TIFFerrorHandler) + { + va_start(ap, fmt); + (*_TIFFerrorHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFerrorHandlerExt) + { + va_start(ap, fmt); + (*_TIFFerrorHandlerExt)(0, module, fmt, ap); + va_end(ap); + } } -void -TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...) +void TIFFErrorExt(thandle_t fd, const char *module, const char *fmt, ...) { - va_list ap; - if (_TIFFerrorHandler) { - va_start(ap, fmt); - (*_TIFFerrorHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFerrorHandlerExt) { - va_start(ap, fmt); - (*_TIFFerrorHandlerExt)(fd, module, fmt, ap); - va_end(ap); - } + va_list ap; + if (_TIFFerrorHandler) + { + va_start(ap, fmt); + (*_TIFFerrorHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFerrorHandlerExt) + { + va_start(ap, fmt); + (*_TIFFerrorHandlerExt)(fd, module, fmt, ap); + va_end(ap); + } } -void _TIFFErrorEarly(TIFFOpenOptions* opts, thandle_t clientdata, const char* module, const char* fmt, ...) +void _TIFFErrorEarly(TIFFOpenOptions *opts, thandle_t clientdata, + const char *module, const char *fmt, ...) { va_list ap; - if (opts && opts->errorhandler) { + if (opts && opts->errorhandler) + { va_start(ap, fmt); - int stop = opts->errorhandler(NULL, opts->errorhandler_user_data, module, fmt, ap); + int stop = opts->errorhandler(NULL, opts->errorhandler_user_data, + module, fmt, ap); va_end(ap); - if (stop) return; + if (stop) + return; } - if (_TIFFerrorHandler) { + if (_TIFFerrorHandler) + { va_start(ap, fmt); (*_TIFFerrorHandler)(module, fmt, ap); va_end(ap); } - if (_TIFFerrorHandlerExt) { + if (_TIFFerrorHandlerExt) + { va_start(ap, fmt); (*_TIFFerrorHandlerExt)(clientdata, module, fmt, ap); va_end(ap); } } - -void TIFFErrorExtR(TIFF* tif, const char* module, const char* fmt, ...) +void TIFFErrorExtR(TIFF *tif, const char *module, const char *fmt, ...) { - va_list ap; - if (tif && tif->tif_errorhandler) { - va_start(ap, fmt); - int stop = (*tif->tif_errorhandler)(tif, tif->tif_errorhandler_user_data, module, fmt, ap); - va_end(ap); - if (stop) return; - } - if (_TIFFerrorHandler) { - va_start(ap, fmt); - (*_TIFFerrorHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFerrorHandlerExt) { - va_start(ap, fmt); - (*_TIFFerrorHandlerExt)(tif ? tif->tif_clientdata : NULL, module, fmt, ap); - va_end(ap); - } + va_list ap; + if (tif && tif->tif_errorhandler) + { + va_start(ap, fmt); + int stop = (*tif->tif_errorhandler)( + tif, tif->tif_errorhandler_user_data, module, fmt, ap); + va_end(ap); + if (stop) + return; + } + if (_TIFFerrorHandler) + { + va_start(ap, fmt); + (*_TIFFerrorHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFerrorHandlerExt) + { + va_start(ap, fmt); + (*_TIFFerrorHandlerExt)(tif ? tif->tif_clientdata : NULL, module, fmt, + ap); + va_end(ap); + } } diff --git a/libtiff/tif_extension.c b/libtiff/tif_extension.c index d0e643d6..1a09e987 100644 --- a/libtiff/tif_extension.c +++ b/libtiff/tif_extension.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -26,25 +26,25 @@ * TIFF Library. * * Various routines support external extension of the tag set, and other - * application extension capabilities. + * application extension capabilities. */ #include "tiffiop.h" -int TIFFGetTagListCount( TIFF *tif ) +int TIFFGetTagListCount(TIFF *tif) { - TIFFDirectory* td = &tif->tif_dir; - + TIFFDirectory *td = &tif->tif_dir; + return td->td_customValueCount; } -uint32_t TIFFGetTagListEntry(TIFF *tif, int tag_index ) +uint32_t TIFFGetTagListEntry(TIFF *tif, int tag_index) { - TIFFDirectory* td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; - if( tag_index < 0 || tag_index >= td->td_customValueCount ) + if (tag_index < 0 || tag_index >= td->td_customValueCount) return (uint32_t)(-1); else return td->td_customValues[tag_index].info->field_tag; @@ -55,27 +55,27 @@ uint32_t TIFFGetTagListEntry(TIFF *tif, int tag_index ) ** structure to application code without giving access to the private ** TIFF structure. */ -TIFFTagMethods *TIFFAccessTagMethods( TIFF *tif ) +TIFFTagMethods *TIFFAccessTagMethods(TIFF *tif) { return &(tif->tif_tagmethods); } -void *TIFFGetClientInfo( TIFF *tif, const char *name ) +void *TIFFGetClientInfo(TIFF *tif, const char *name) { TIFFClientInfoLink *psLink = tif->tif_clientinfo; - while( psLink != NULL && strcmp(psLink->name,name) != 0 ) + while (psLink != NULL && strcmp(psLink->name, name) != 0) psLink = psLink->next; - if( psLink != NULL ) + if (psLink != NULL) return psLink->data; else return NULL; } -void TIFFSetClientInfo( TIFF *tif, void *data, const char *name ) +void TIFFSetClientInfo(TIFF *tif, void *data, const char *name) { TIFFClientInfoLink *psLink = tif->tif_clientinfo; @@ -84,10 +84,10 @@ void TIFFSetClientInfo( TIFF *tif, void *data, const char *name ) ** Do we have an existing link with this name? If so, just ** set it. */ - while( psLink != NULL && strcmp(psLink->name,name) != 0 ) + while (psLink != NULL && strcmp(psLink->name, name) != 0) psLink = psLink->next; - if( psLink != NULL ) + if (psLink != NULL) { psLink->data = data; return; @@ -97,11 +97,12 @@ void TIFFSetClientInfo( TIFF *tif, void *data, const char *name ) ** Create a new link. */ - psLink = (TIFFClientInfoLink *) _TIFFmallocExt(tif, sizeof(TIFFClientInfoLink)); - assert (psLink != NULL); + psLink = + (TIFFClientInfoLink *)_TIFFmallocExt(tif, sizeof(TIFFClientInfoLink)); + assert(psLink != NULL); psLink->next = tif->tif_clientinfo; - psLink->name = (char *) _TIFFmallocExt(tif, (tmsize_t)(strlen(name)+1)); - assert (psLink->name != NULL); + psLink->name = (char *)_TIFFmallocExt(tif, (tmsize_t)(strlen(name) + 1)); + assert(psLink->name != NULL); strcpy(psLink->name, name); psLink->data = data; diff --git a/libtiff/tif_fax3.c b/libtiff/tif_fax3.c index 5e0012b7..9d66fc0e 100644 --- a/libtiff/tif_fax3.c +++ b/libtiff/tif_fax3.c @@ -2,23 +2,23 @@ * Copyright (c) 1990-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -37,7 +37,7 @@ * Copyright (C) 1990, 1995 Frank D. Cringle. */ #include "tif_fax3.h" -#define G3CODES +#define G3CODES #include "t4.h" #include <stdio.h> @@ -45,51 +45,57 @@ * Compression+decompression state blocks are * derived from this ``base state'' block. */ -typedef struct { - int rw_mode; /* O_RDONLY for decode, else encode */ - int mode; /* operating mode */ - tmsize_t rowbytes; /* bytes in a decoded scanline */ - uint32_t rowpixels; /* pixels in a scanline */ - - uint16_t cleanfaxdata; /* CleanFaxData tag */ - uint32_t badfaxrun; /* BadFaxRun tag */ - uint32_t badfaxlines; /* BadFaxLines tag */ - uint32_t groupoptions; /* Group 3/4 options tag */ - - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ +typedef struct +{ + int rw_mode; /* O_RDONLY for decode, else encode */ + int mode; /* operating mode */ + tmsize_t rowbytes; /* bytes in a decoded scanline */ + uint32_t rowpixels; /* pixels in a scanline */ + + uint16_t cleanfaxdata; /* CleanFaxData tag */ + uint32_t badfaxrun; /* BadFaxRun tag */ + uint32_t badfaxlines; /* BadFaxLines tag */ + uint32_t groupoptions; /* Group 3/4 options tag */ + + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ } Fax3BaseState; -#define Fax3State(tif) ((Fax3BaseState*) (tif)->tif_data) - -typedef enum { G3_1D, G3_2D } Ttag; -typedef struct { - Fax3BaseState b; - - /* Decoder state info */ - const unsigned char* bitmap; /* bit reversal table */ - uint32_t data; /* current i/o byte/word */ - int bit; /* current i/o bit in byte */ - int EOLcnt; /* count of EOL codes recognized */ - TIFFFaxFillFunc fill; /* fill routine */ - uint32_t* runs; /* b&w runs for current/previous row */ - uint32_t nruns; /* size of the refruns / curruns arrays */ - uint32_t* refruns; /* runs for reference line */ - uint32_t* curruns; /* runs for current line */ - - /* Encoder state info */ - Ttag tag; /* encoding state */ - unsigned char* refline; /* reference line for 2d decoding */ - int k; /* #rows left that can be 2d encoded */ - int maxk; /* max #rows that can be 2d encoded */ - - int line; +#define Fax3State(tif) ((Fax3BaseState *)(tif)->tif_data) + +typedef enum +{ + G3_1D, + G3_2D +} Ttag; +typedef struct +{ + Fax3BaseState b; + + /* Decoder state info */ + const unsigned char *bitmap; /* bit reversal table */ + uint32_t data; /* current i/o byte/word */ + int bit; /* current i/o bit in byte */ + int EOLcnt; /* count of EOL codes recognized */ + TIFFFaxFillFunc fill; /* fill routine */ + uint32_t *runs; /* b&w runs for current/previous row */ + uint32_t nruns; /* size of the refruns / curruns arrays */ + uint32_t *refruns; /* runs for reference line */ + uint32_t *curruns; /* runs for current line */ + + /* Encoder state info */ + Ttag tag; /* encoding state */ + unsigned char *refline; /* reference line for 2d decoding */ + int k; /* #rows left that can be 2d encoded */ + int maxk; /* max #rows that can be 2d encoded */ + + int line; } Fax3CodecState; -#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif)) -#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif)) +#define DecoderState(tif) ((Fax3CodecState *)Fax3State(tif)) +#define EncoderState(tif) ((Fax3CodecState *)Fax3State(tif)) #define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING) -#define isAligned(p,t) ((((size_t)(p)) & (sizeof (t)-1)) == 0) +#define isAligned(p, t) ((((size_t)(p)) & (sizeof(t) - 1)) == 0) /* * Group 3 and Group 4 Decoding. @@ -99,76 +105,81 @@ typedef struct { * These macros glue the TIFF library state to * the state expected by Frank's decoder. */ -#define DECLARE_STATE(tif, sp, mod) \ - static const char module[] = mod; \ - Fax3CodecState* sp = DecoderState(tif); \ - int a0; /* reference element */ \ - int lastx = sp->b.rowpixels; /* last element in row */ \ - uint32_t BitAcc; /* bit accumulator */ \ - int BitsAvail; /* # valid bits in BitAcc */ \ - int RunLength; /* length of current run */ \ - unsigned char* cp; /* next byte of input data */ \ - unsigned char* ep; /* end of input data */ \ - uint32_t* pa; /* place to stuff next run */ \ - uint32_t* thisrun; /* current row's run array */ \ - int EOLcnt; /* # EOL codes recognized */ \ - const unsigned char* bitmap = sp->bitmap; /* input data bit reverser */ \ - const TIFFFaxTabEnt* TabEnt -#define DECLARE_STATE_2D(tif, sp, mod) \ - DECLARE_STATE(tif, sp, mod); \ - int b1; /* next change on prev line */ \ - uint32_t* pb /* next run in reference line */\ -/* - * Load any state that may be changed during decoding. - */ -#define CACHE_STATE(tif, sp) do { \ - BitAcc = sp->data; \ - BitsAvail = sp->bit; \ - EOLcnt = sp->EOLcnt; \ - cp = (unsigned char*) tif->tif_rawcp; \ - ep = cp + tif->tif_rawcc; \ -} while (0) +#define DECLARE_STATE(tif, sp, mod) \ + static const char module[] = mod; \ + Fax3CodecState *sp = DecoderState(tif); \ + int a0; /* reference element */ \ + int lastx = sp->b.rowpixels; /* last element in row */ \ + uint32_t BitAcc; /* bit accumulator */ \ + int BitsAvail; /* # valid bits in BitAcc */ \ + int RunLength; /* length of current run */ \ + unsigned char *cp; /* next byte of input data */ \ + unsigned char *ep; /* end of input data */ \ + uint32_t *pa; /* place to stuff next run */ \ + uint32_t *thisrun; /* current row's run array */ \ + int EOLcnt; /* # EOL codes recognized */ \ + const unsigned char *bitmap = sp->bitmap; /* input data bit reverser */ \ + const TIFFFaxTabEnt *TabEnt +#define DECLARE_STATE_2D(tif, sp, mod) \ + DECLARE_STATE(tif, sp, mod); \ + int b1; /* next change on prev line */ \ + uint32_t \ + *pb /* next run in reference line */ /* \ + * Load any state that may be \ + * changed during decoding. \ + */ +#define CACHE_STATE(tif, sp) \ + do \ + { \ + BitAcc = sp->data; \ + BitsAvail = sp->bit; \ + EOLcnt = sp->EOLcnt; \ + cp = (unsigned char *)tif->tif_rawcp; \ + ep = cp + tif->tif_rawcc; \ + } while (0) /* * Save state possibly changed during decoding. */ -#define UNCACHE_STATE(tif, sp) do { \ - sp->bit = BitsAvail; \ - sp->data = BitAcc; \ - sp->EOLcnt = EOLcnt; \ - tif->tif_rawcc -= (tmsize_t)((uint8_t*) cp - tif->tif_rawcp); \ - tif->tif_rawcp = (uint8_t*) cp; \ -} while (0) +#define UNCACHE_STATE(tif, sp) \ + do \ + { \ + sp->bit = BitsAvail; \ + sp->data = BitAcc; \ + sp->EOLcnt = EOLcnt; \ + tif->tif_rawcc -= (tmsize_t)((uint8_t *)cp - tif->tif_rawcp); \ + tif->tif_rawcp = (uint8_t *)cp; \ + } while (0) /* * Setup state for decoding a strip. */ -static int -Fax3PreDecode(TIFF* tif, uint16_t s) +static int Fax3PreDecode(TIFF *tif, uint16_t s) { - Fax3CodecState* sp = DecoderState(tif); - - (void) s; - assert(sp != NULL); - sp->bit = 0; /* force initial read */ - sp->data = 0; - sp->EOLcnt = 0; /* force initial scan for EOL */ - /* - * Decoder assumes lsb-to-msb bit order. Note that we select - * this here rather than in Fax3SetupState so that viewers can - * hold the image open, fiddle with the FillOrder tag value, - * and then re-decode the image. Otherwise they'd need to close - * and open the image to get the state reset. - */ - sp->bitmap = - TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB); - sp->curruns = sp->runs; - if (sp->refruns) { /* init reference line to white */ - sp->refruns = sp->runs + sp->nruns; - sp->refruns[0] = (uint32_t) sp->b.rowpixels; - sp->refruns[1] = 0; - } - sp->line = 0; - return (1); + Fax3CodecState *sp = DecoderState(tif); + + (void)s; + assert(sp != NULL); + sp->bit = 0; /* force initial read */ + sp->data = 0; + sp->EOLcnt = 0; /* force initial scan for EOL */ + /* + * Decoder assumes lsb-to-msb bit order. Note that we select + * this here rather than in Fax3SetupState so that viewers can + * hold the image open, fiddle with the FillOrder tag value, + * and then re-decode the image. Otherwise they'd need to close + * and open the image to get the state reset. + */ + sp->bitmap = + TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB); + sp->curruns = sp->runs; + if (sp->refruns) + { /* init reference line to white */ + sp->refruns = sp->runs + sp->nruns; + sp->refruns[0] = (uint32_t)sp->b.rowpixels; + sp->refruns[1] = 0; + } + sp->line = 0; + return (1); } /* @@ -177,49 +188,53 @@ Fax3PreDecode(TIFF* tif, uint16_t s) * overriding the definitions used by the decoder. */ -static void -Fax3Unexpected(const char* module, TIFF* tif, uint32_t line, uint32_t a0) +static void Fax3Unexpected(const char *module, TIFF *tif, uint32_t line, + uint32_t a0) { - TIFFErrorExtR(tif, module, "Bad code word at line %"PRIu32" of %s %"PRIu32" (x %"PRIu32")", - line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0); + TIFFErrorExtR(tif, module, + "Bad code word at line %" PRIu32 " of %s %" PRIu32 + " (x %" PRIu32 ")", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0); } -#define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0) +#define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0) -static void -Fax3Extension(const char* module, TIFF* tif, uint32_t line, uint32_t a0) +static void Fax3Extension(const char *module, TIFF *tif, uint32_t line, + uint32_t a0) { - TIFFErrorExtR(tif, module, - "Uncompressed data (not supported) at line %"PRIu32" of %s %"PRIu32" (x %"PRIu32")", - line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0); + TIFFErrorExtR(tif, module, + "Uncompressed data (not supported) at line %" PRIu32 + " of %s %" PRIu32 " (x %" PRIu32 ")", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0); } -#define extension(a0) Fax3Extension(module, tif, sp->line, a0) +#define extension(a0) Fax3Extension(module, tif, sp->line, a0) -static void -Fax3BadLength(const char* module, TIFF* tif, uint32_t line, uint32_t a0, uint32_t lastx) +static void Fax3BadLength(const char *module, TIFF *tif, uint32_t line, + uint32_t a0, uint32_t lastx) { - TIFFWarningExtR(tif, module, "%s at line %"PRIu32" of %s %"PRIu32" (got %"PRIu32", expected %"PRIu32")", - a0 < lastx ? "Premature EOL" : "Line length mismatch", - line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0, lastx); + TIFFWarningExtR(tif, module, + "%s at line %" PRIu32 " of %s %" PRIu32 " (got %" PRIu32 + ", expected %" PRIu32 ")", + a0 < lastx ? "Premature EOL" : "Line length mismatch", line, + isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0, + lastx); } -#define badlength(a0,lastx) Fax3BadLength(module, tif, sp->line, a0, lastx) +#define badlength(a0, lastx) Fax3BadLength(module, tif, sp->line, a0, lastx) -static void -Fax3PrematureEOF(const char* module, TIFF* tif, uint32_t line, uint32_t a0) +static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line, + uint32_t a0) { - TIFFWarningExtR(tif, module, "Premature EOF at line %"PRIu32" of %s %"PRIu32" (x %"PRIu32")", - line, isTiled(tif) ? "tile" : "strip", - (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), - a0); + TIFFWarningExtR(tif, module, + "Premature EOF at line %" PRIu32 " of %s %" PRIu32 + " (x %" PRIu32 ")", + line, isTiled(tif) ? "tile" : "strip", + (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0); } -#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0) +#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0) -#define Nop +#define Nop /** * Decode the requested amount of G3 1D-encoded data. @@ -228,219 +243,240 @@ Fax3PrematureEOF(const char* module, TIFF* tif, uint32_t line, uint32_t a0) * @param s number of planes (ignored) * @returns 1 for success, -1 in case of error */ -static int -Fax3Decode1D(TIFF* tif, uint8_t* buf, tmsize_t occ, uint16_t s) +static int Fax3Decode1D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - DECLARE_STATE(tif, sp, "Fax3Decode1D"); - (void) s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - thisrun = sp->curruns; - while (occ > 0) { - a0 = 0; - RunLength = 0; - pa = thisrun; + DECLARE_STATE(tif, sp, "Fax3Decode1D"); + (void)s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + thisrun = sp->curruns; + while (occ > 0) + { + a0 = 0; + RunLength = 0; + pa = thisrun; #ifdef FAX3_DEBUG - printf("\nBitAcc=%08"PRIX32", BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %"PRIu32"\n", tif->tif_row); - fflush(stdout); + printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %" PRIu32 "\n", tif->tif_row); + fflush(stdout); #endif - SYNC_EOL(EOF1D); - EXPAND1D(EOF1Da); - (*sp->fill)(buf, thisrun, pa, lastx); - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOF1D: /* premature EOF */ - CLEANUP_RUNS(); - EOF1Da: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return (-1); - } - UNCACHE_STATE(tif, sp); - return (1); + SYNC_EOL(EOF1D); + EXPAND1D(EOF1Da); + (*sp->fill)(buf, thisrun, pa, lastx); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOF1D: /* premature EOF */ + CLEANUP_RUNS(); + EOF1Da: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); } -#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } +#define SWAP(t, a, b) \ + { \ + t x; \ + x = (a); \ + (a) = (b); \ + (b) = x; \ + } /* * Decode the requested amount of G3 2D-encoded data. */ -static int -Fax3Decode2D(TIFF* tif, uint8_t* buf, tmsize_t occ, uint16_t s) +static int Fax3Decode2D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - DECLARE_STATE_2D(tif, sp, "Fax3Decode2D"); - int is1D; /* current line is 1d/2d-encoded */ - (void) s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - while (occ > 0) { - a0 = 0; - RunLength = 0; - pa = thisrun = sp->curruns; + DECLARE_STATE_2D(tif, sp, "Fax3Decode2D"); + int is1D; /* current line is 1d/2d-encoded */ + (void)s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + while (occ > 0) + { + a0 = 0; + RunLength = 0; + pa = thisrun = sp->curruns; #ifdef FAX3_DEBUG - printf("\nBitAcc=%08"PRIX32", BitsAvail = %d EOLcnt = %d", - BitAcc, BitsAvail, EOLcnt); + printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d EOLcnt = %d", BitAcc, + BitsAvail, EOLcnt); #endif - SYNC_EOL(EOF2D); - NeedBits8(1, EOF2D); - is1D = GetBits(1); /* 1D/2D-encoding tag bit */ - ClrBits(1); + SYNC_EOL(EOF2D); + NeedBits8(1, EOF2D); + is1D = GetBits(1); /* 1D/2D-encoding tag bit */ + ClrBits(1); #ifdef FAX3_DEBUG - printf(" %s\n-------------------- %"PRIu32"\n", - is1D ? "1D" : "2D", tif->tif_row); - fflush(stdout); + printf(" %s\n-------------------- %" PRIu32 "\n", is1D ? "1D" : "2D", + tif->tif_row); + fflush(stdout); #endif - pb = sp->refruns; - b1 = *pb++; - if (is1D) - EXPAND1D(EOF2Da); - else - EXPAND2D(EOF2Da); - (*sp->fill)(buf, thisrun, pa, lastx); - if (pa < thisrun + sp->nruns) { - SETVALUE(0); /* imaginary change for reference */ - } - SWAP(uint32_t*, sp->curruns, sp->refruns); - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOF2D: /* premature EOF */ - CLEANUP_RUNS(); - EOF2Da: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return (-1); - } - UNCACHE_STATE(tif, sp); - return (1); + pb = sp->refruns; + b1 = *pb++; + if (is1D) + EXPAND1D(EOF2Da); + else + EXPAND2D(EOF2Da); + (*sp->fill)(buf, thisrun, pa, lastx); + if (pa < thisrun + sp->nruns) + { + SETVALUE(0); /* imaginary change for reference */ + } + SWAP(uint32_t *, sp->curruns, sp->refruns); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOF2D: /* premature EOF */ + CLEANUP_RUNS(); + EOF2Da: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); } #undef SWAP -# define FILL(n, cp) \ - for (int32_t ifill = 0; ifill < (n); ++ifill) \ - { \ - (cp)[ifill] = 0xff; \ - } \ +#define FILL(n, cp) \ + for (int32_t ifill = 0; ifill < (n); ++ifill) \ + { \ + (cp)[ifill] = 0xff; \ + } \ (cp) += (n); -# define ZERO(n, cp) \ - for (int32_t izero = 0; izero < (n); ++izero) \ - { \ - (cp)[izero] = 0; \ - } \ +#define ZERO(n, cp) \ + for (int32_t izero = 0; izero < (n); ++izero) \ + { \ + (cp)[izero] = 0; \ + } \ (cp) += (n); /* * Bit-fill a row according to the white/black * runs generated during G3/G4 decoding. */ -void -_TIFFFax3fillruns(unsigned char* buf, uint32_t* runs, uint32_t* erun, uint32_t lastx) +void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun, + uint32_t lastx) { - static const unsigned char _fillmasks[] = - { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; - unsigned char* cp; - uint32_t x, bx, run; - int32_t n, nw; - int64_t* lp; - - if ((erun-runs)&1) - *erun++ = 0; - x = 0; - for (; runs < erun; runs += 2) { - run = runs[0]; - if (x+run > lastx || run > lastx ) - run = runs[0] = (uint32_t) (lastx - x); - if (run) { - cp = buf + (x>>3); - bx = x&7; - if (run > 8-bx) { - if (bx) { /* align to byte boundary */ - *cp++ &= 0xff << (8-bx); - run -= 8-bx; - } - if( (n = run >> 3) != 0 ) { /* multiple bytes to fill */ - if ((n/sizeof (int64_t)) > 1) { - /* - * Align to int64_tword boundary and fill. - */ - for (; n && !isAligned(cp, int64_t); n--) - *cp++ = 0x00; - lp = (int64_t*) cp; - nw = (int32_t)(n / sizeof (int64_t)); - n -= nw * sizeof (int64_t); - do { - *lp++ = 0L; - } while (--nw); - cp = (unsigned char*) lp; - } - ZERO(n, cp); - run &= 7; - } - if (run) - cp[0] &= 0xff >> run; - } else - cp[0] &= ~(_fillmasks[run]>>bx); - x += runs[0]; - } - run = runs[1]; - if (x+run > lastx || run > lastx ) - run = runs[1] = lastx - x; - if (run) { - cp = buf + (x>>3); - bx = x&7; - if (run > 8-bx) { - if (bx) { /* align to byte boundary */ - *cp++ |= 0xff >> bx; - run -= 8-bx; - } - if( (n = run>>3) != 0 ) { /* multiple bytes to fill */ - if ((n/sizeof (int64_t)) > 1) { - /* - * Align to int64_t boundary and fill. - */ - for (; n && !isAligned(cp, int64_t); n--) - *cp++ = 0xff; - lp = (int64_t*) cp; - nw = (int32_t)(n / sizeof (int64_t)); - n -= nw * sizeof (int64_t); - do { - *lp++ = -1L; - } while (--nw); - cp = (unsigned char*) lp; - } - FILL(n, cp); - run &= 7; - } - /* Explicit 0xff masking to make icc -check=conversions happy */ - if (run) - cp[0] = (unsigned char)((cp[0] | (0xff00 >> run))&0xff); - } else - cp[0] |= _fillmasks[run]>>bx; - x += runs[1]; - } - } - assert(x == lastx); + static const unsigned char _fillmasks[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, + 0xf8, 0xfc, 0xfe, 0xff}; + unsigned char *cp; + uint32_t x, bx, run; + int32_t n, nw; + int64_t *lp; + + if ((erun - runs) & 1) + *erun++ = 0; + x = 0; + for (; runs < erun; runs += 2) + { + run = runs[0]; + if (x + run > lastx || run > lastx) + run = runs[0] = (uint32_t)(lastx - x); + if (run) + { + cp = buf + (x >> 3); + bx = x & 7; + if (run > 8 - bx) + { + if (bx) + { /* align to byte boundary */ + *cp++ &= 0xff << (8 - bx); + run -= 8 - bx; + } + if ((n = run >> 3) != 0) + { /* multiple bytes to fill */ + if ((n / sizeof(int64_t)) > 1) + { + /* + * Align to int64_tword boundary and fill. + */ + for (; n && !isAligned(cp, int64_t); n--) + *cp++ = 0x00; + lp = (int64_t *)cp; + nw = (int32_t)(n / sizeof(int64_t)); + n -= nw * sizeof(int64_t); + do + { + *lp++ = 0L; + } while (--nw); + cp = (unsigned char *)lp; + } + ZERO(n, cp); + run &= 7; + } + if (run) + cp[0] &= 0xff >> run; + } + else + cp[0] &= ~(_fillmasks[run] >> bx); + x += runs[0]; + } + run = runs[1]; + if (x + run > lastx || run > lastx) + run = runs[1] = lastx - x; + if (run) + { + cp = buf + (x >> 3); + bx = x & 7; + if (run > 8 - bx) + { + if (bx) + { /* align to byte boundary */ + *cp++ |= 0xff >> bx; + run -= 8 - bx; + } + if ((n = run >> 3) != 0) + { /* multiple bytes to fill */ + if ((n / sizeof(int64_t)) > 1) + { + /* + * Align to int64_t boundary and fill. + */ + for (; n && !isAligned(cp, int64_t); n--) + *cp++ = 0xff; + lp = (int64_t *)cp; + nw = (int32_t)(n / sizeof(int64_t)); + n -= nw * sizeof(int64_t); + do + { + *lp++ = -1L; + } while (--nw); + cp = (unsigned char *)lp; + } + FILL(n, cp); + run &= 7; + } + /* Explicit 0xff masking to make icc -check=conversions happy */ + if (run) + cp[0] = (unsigned char)((cp[0] | (0xff00 >> run)) & 0xff); + } + else + cp[0] |= _fillmasks[run] >> bx; + x += runs[1]; + } + } + assert(x == lastx); } -#undef ZERO -#undef FILL +#undef ZERO +#undef FILL -static int -Fax3FixupTags(TIFF* tif) +static int Fax3FixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } /* @@ -450,175 +486,188 @@ Fax3FixupTags(TIFF* tif) * or not decoding or encoding is being done and whether * 1D- or 2D-encoded data is involved. */ -static int -Fax3SetupState(TIFF* tif) +static int Fax3SetupState(TIFF *tif) { - static const char module[] = "Fax3SetupState"; - TIFFDirectory* td = &tif->tif_dir; - Fax3BaseState* sp = Fax3State(tif); - int needsRefLine; - Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif); - tmsize_t rowbytes; - uint32_t rowpixels; - - if (td->td_bitspersample != 1) { - TIFFErrorExtR(tif, module, - "Bits/sample must be 1 for Group 3/4 encoding/decoding"); - return (0); - } - /* - * Calculate the scanline/tile widths. - */ - if (isTiled(tif)) { - rowbytes = TIFFTileRowSize(tif); - rowpixels = td->td_tilewidth; - } else { - rowbytes = TIFFScanlineSize(tif); - rowpixels = td->td_imagewidth; - } - if ((int64_t)rowbytes < ((int64_t)rowpixels + 7) / 8) - { - TIFFErrorExtR(tif, module, - "Inconsistent number of bytes per row : rowbytes=%" PRId64 " rowpixels=%" PRIu32, - (int64_t) rowbytes, rowpixels); - return (0); - } - sp->rowbytes = rowbytes; - sp->rowpixels = rowpixels; - /* - * Allocate any additional space required for decoding/encoding. - */ - needsRefLine = ( - (sp->groupoptions & GROUP3OPT_2DENCODING) || - td->td_compression == COMPRESSION_CCITTFAX4 - ); - - /* - Assure that allocation computations do not overflow. - - TIFFroundup and TIFFSafeMultiply return zero on integer overflow - */ - dsp->runs=(uint32_t*) NULL; - dsp->nruns = TIFFroundup_32(rowpixels,32); - if (needsRefLine) { - dsp->nruns = TIFFSafeMultiply(uint32_t, dsp->nruns, 2); - } - if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32_t, dsp->nruns, 2) == 0)) { - TIFFErrorExtR(tif, tif->tif_name, - "Row pixels integer overflow (rowpixels %"PRIu32")", - rowpixels); - return (0); - } - dsp->runs = (uint32_t*) _TIFFCheckMalloc(tif, - TIFFSafeMultiply(uint32_t, dsp->nruns, 2), - sizeof (uint32_t), - "for Group 3/4 run arrays"); - if (dsp->runs == NULL) - return (0); - memset( dsp->runs, 0, TIFFSafeMultiply(uint32_t,dsp->nruns,2)*sizeof(uint32_t)); - dsp->curruns = dsp->runs; - if (needsRefLine) - dsp->refruns = dsp->runs + dsp->nruns; - else - dsp->refruns = NULL; - if (td->td_compression == COMPRESSION_CCITTFAX3 - && is2DEncoding(dsp)) { /* NB: default is 1D routine */ - tif->tif_decoderow = Fax3Decode2D; - tif->tif_decodestrip = Fax3Decode2D; - tif->tif_decodetile = Fax3Decode2D; - } - - if (needsRefLine) { /* 2d encoding */ - Fax3CodecState* esp = EncoderState(tif); - /* - * 2d encoding requires a scanline - * buffer for the ``reference line''; the - * scanline against which delta encoding - * is referenced. The reference line must - * be initialized to be ``white'' (done elsewhere). - */ - esp->refline = (unsigned char*) _TIFFmallocExt(tif, rowbytes); - if (esp->refline == NULL) { - TIFFErrorExtR(tif, module, - "No space for Group 3/4 reference line"); - return (0); - } - } else /* 1d encoding */ - EncoderState(tif)->refline = NULL; - - return (1); + static const char module[] = "Fax3SetupState"; + TIFFDirectory *td = &tif->tif_dir; + Fax3BaseState *sp = Fax3State(tif); + int needsRefLine; + Fax3CodecState *dsp = (Fax3CodecState *)Fax3State(tif); + tmsize_t rowbytes; + uint32_t rowpixels; + + if (td->td_bitspersample != 1) + { + TIFFErrorExtR(tif, module, + "Bits/sample must be 1 for Group 3/4 encoding/decoding"); + return (0); + } + /* + * Calculate the scanline/tile widths. + */ + if (isTiled(tif)) + { + rowbytes = TIFFTileRowSize(tif); + rowpixels = td->td_tilewidth; + } + else + { + rowbytes = TIFFScanlineSize(tif); + rowpixels = td->td_imagewidth; + } + if ((int64_t)rowbytes < ((int64_t)rowpixels + 7) / 8) + { + TIFFErrorExtR(tif, module, + "Inconsistent number of bytes per row : rowbytes=%" PRId64 + " rowpixels=%" PRIu32, + (int64_t)rowbytes, rowpixels); + return (0); + } + sp->rowbytes = rowbytes; + sp->rowpixels = rowpixels; + /* + * Allocate any additional space required for decoding/encoding. + */ + needsRefLine = ((sp->groupoptions & GROUP3OPT_2DENCODING) || + td->td_compression == COMPRESSION_CCITTFAX4); + + /* + Assure that allocation computations do not overflow. + + TIFFroundup and TIFFSafeMultiply return zero on integer overflow + */ + dsp->runs = (uint32_t *)NULL; + dsp->nruns = TIFFroundup_32(rowpixels, 32); + if (needsRefLine) + { + dsp->nruns = TIFFSafeMultiply(uint32_t, dsp->nruns, 2); + } + if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32_t, dsp->nruns, 2) == 0)) + { + TIFFErrorExtR(tif, tif->tif_name, + "Row pixels integer overflow (rowpixels %" PRIu32 ")", + rowpixels); + return (0); + } + dsp->runs = (uint32_t *)_TIFFCheckMalloc( + tif, TIFFSafeMultiply(uint32_t, dsp->nruns, 2), sizeof(uint32_t), + "for Group 3/4 run arrays"); + if (dsp->runs == NULL) + return (0); + memset(dsp->runs, 0, + TIFFSafeMultiply(uint32_t, dsp->nruns, 2) * sizeof(uint32_t)); + dsp->curruns = dsp->runs; + if (needsRefLine) + dsp->refruns = dsp->runs + dsp->nruns; + else + dsp->refruns = NULL; + if (td->td_compression == COMPRESSION_CCITTFAX3 && is2DEncoding(dsp)) + { /* NB: default is 1D routine */ + tif->tif_decoderow = Fax3Decode2D; + tif->tif_decodestrip = Fax3Decode2D; + tif->tif_decodetile = Fax3Decode2D; + } + + if (needsRefLine) + { /* 2d encoding */ + Fax3CodecState *esp = EncoderState(tif); + /* + * 2d encoding requires a scanline + * buffer for the ``reference line''; the + * scanline against which delta encoding + * is referenced. The reference line must + * be initialized to be ``white'' (done elsewhere). + */ + esp->refline = (unsigned char *)_TIFFmallocExt(tif, rowbytes); + if (esp->refline == NULL) + { + TIFFErrorExtR(tif, module, "No space for Group 3/4 reference line"); + return (0); + } + } + else /* 1d encoding */ + EncoderState(tif)->refline = NULL; + + return (1); } /* * CCITT Group 3 FAX Encoding. */ -#define Fax3FlushBits(tif, sp) { \ - if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) { \ - if( !TIFFFlushData1(tif) ) \ - return 0; \ - } \ - *(tif)->tif_rawcp++ = (uint8_t) (sp)->data; \ - (tif)->tif_rawcc++; \ - (sp)->data = 0, (sp)->bit = 8; \ -} -#define _FlushBits(tif) { \ - if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) { \ - if( !TIFFFlushData1(tif) ) \ - return 0; \ - } \ - *(tif)->tif_rawcp++ = (uint8_t) data; \ - (tif)->tif_rawcc++; \ - data = 0, bit = 8; \ -} -static const int _msbmask[9] = - { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; -#define _PutBits(tif, bits, length) { \ - while (length > bit) { \ - data |= bits >> (length - bit); \ - length -= bit; \ - _FlushBits(tif); \ - } \ - assert( length < 9 ); \ - data |= (bits & _msbmask[length]) << (bit - length); \ - bit -= length; \ - if (bit == 0) \ - _FlushBits(tif); \ -} - +#define Fax3FlushBits(tif, sp) \ + { \ + if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ + { \ + if (!TIFFFlushData1(tif)) \ + return 0; \ + } \ + *(tif)->tif_rawcp++ = (uint8_t)(sp)->data; \ + (tif)->tif_rawcc++; \ + (sp)->data = 0, (sp)->bit = 8; \ + } +#define _FlushBits(tif) \ + { \ + if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \ + { \ + if (!TIFFFlushData1(tif)) \ + return 0; \ + } \ + *(tif)->tif_rawcp++ = (uint8_t)data; \ + (tif)->tif_rawcc++; \ + data = 0, bit = 8; \ + } +static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, + 0x1f, 0x3f, 0x7f, 0xff}; +#define _PutBits(tif, bits, length) \ + { \ + while (length > bit) \ + { \ + data |= bits >> (length - bit); \ + length -= bit; \ + _FlushBits(tif); \ + } \ + assert(length < 9); \ + data |= (bits & _msbmask[length]) << (bit - length); \ + bit -= length; \ + if (bit == 0) \ + _FlushBits(tif); \ + } + /* * Write a variable-length bit-value to * the output stream. Values are * assumed to be at most 16 bits. */ -static int -Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length) +static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length) { - Fax3CodecState* sp = EncoderState(tif); - unsigned int bit = sp->bit; - int data = sp->data; + Fax3CodecState *sp = EncoderState(tif); + unsigned int bit = sp->bit; + int data = sp->data; - _PutBits(tif, bits, length); + _PutBits(tif, bits, length); - sp->data = data; - sp->bit = bit; - return 1; + sp->data = data; + sp->bit = bit; + return 1; } /* * Write a code to the output stream. */ -#define putcode(tif, te) Fax3PutBits(tif, (te)->code, (te)->length) +#define putcode(tif, te) Fax3PutBits(tif, (te)->code, (te)->length) #ifdef FAX3_DEBUG -#define DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B") -#define DEBUG_PRINT(what,len) { \ - int t; \ - printf("%08"PRIX32"/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), len); \ - for (t = length-1; t >= 0; t--) \ - putchar(code & (1<<t) ? '1' : '0'); \ - putchar('\n'); \ -} +#define DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B") +#define DEBUG_PRINT(what, len) \ + { \ + int t; \ + printf("%08" PRIX32 "/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), \ + len); \ + for (t = length - 1; t >= 0; t--) \ + putchar(code & (1 << t) ? '1' : '0'); \ + putchar('\n'); \ + } #endif /* @@ -627,46 +676,47 @@ Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length) * appropriate table that holds the make-up and * terminating codes is supplied. */ -static int -putspan(TIFF* tif, int32_t span, const tableentry* tab) +static int putspan(TIFF *tif, int32_t span, const tableentry *tab) { - Fax3CodecState* sp = EncoderState(tif); - unsigned int bit = sp->bit; - int data = sp->data; - unsigned int code, length; - - while (span >= 2624) { - const tableentry* te = &tab[63 + (2560>>6)]; - code = te->code; - length = te->length; + Fax3CodecState *sp = EncoderState(tif); + unsigned int bit = sp->bit; + int data = sp->data; + unsigned int code, length; + + while (span >= 2624) + { + const tableentry *te = &tab[63 + (2560 >> 6)]; + code = te->code; + length = te->length; #ifdef FAX3_DEBUG - DEBUG_PRINT("MakeUp", te->runlen); + DEBUG_PRINT("MakeUp", te->runlen); #endif - _PutBits(tif, code, length); - span -= te->runlen; - } - if (span >= 64) { - const tableentry* te = &tab[63 + (span>>6)]; - assert(te->runlen == 64*(span>>6)); - code = te->code; - length = te->length; + _PutBits(tif, code, length); + span -= te->runlen; + } + if (span >= 64) + { + const tableentry *te = &tab[63 + (span >> 6)]; + assert(te->runlen == 64 * (span >> 6)); + code = te->code; + length = te->length; #ifdef FAX3_DEBUG - DEBUG_PRINT("MakeUp", te->runlen); + DEBUG_PRINT("MakeUp", te->runlen); #endif - _PutBits(tif, code, length); - span -= te->runlen; - } - code = tab[span].code; - length = tab[span].length; + _PutBits(tif, code, length); + span -= te->runlen; + } + code = tab[span].code; + length = tab[span].length; #ifdef FAX3_DEBUG - DEBUG_PRINT(" Term", tab[span].runlen); + DEBUG_PRINT(" Term", tab[span].runlen); #endif - _PutBits(tif, code, length); + _PutBits(tif, code, length); - sp->data = data; - sp->bit = bit; + sp->data = data; + sp->bit = bit; - return 1; + return 1; } /* @@ -675,121 +725,124 @@ putspan(TIFF* tif, int32_t span, const tableentry* tab) * here. We also handle writing the tag bit for the next * scanline when doing 2d encoding. */ -static int -Fax3PutEOL(TIFF* tif) +static int Fax3PutEOL(TIFF *tif) { - Fax3CodecState* sp = EncoderState(tif); - unsigned int bit = sp->bit; - int data = sp->data; - unsigned int code, length, tparm; - - if (sp->b.groupoptions & GROUP3OPT_FILLBITS) { - /* - * Force bit alignment so EOL will terminate on - * a byte boundary. That is, force the bit alignment - * to 16-12 = 4 before putting out the EOL code. - */ - int align = 8 - 4; - if (align != sp->bit) { - if (align > sp->bit) - align = sp->bit + (8 - align); - else - align = sp->bit - align; - tparm=align; - _PutBits(tif, 0, tparm); - } - } - code = EOL; - length = 12; - if (is2DEncoding(sp)) { - code = (code<<1) | (sp->tag == G3_1D); - length++; - } - _PutBits(tif, code, length); - - sp->data = data; - sp->bit = bit; - - return 1; + Fax3CodecState *sp = EncoderState(tif); + unsigned int bit = sp->bit; + int data = sp->data; + unsigned int code, length, tparm; + + if (sp->b.groupoptions & GROUP3OPT_FILLBITS) + { + /* + * Force bit alignment so EOL will terminate on + * a byte boundary. That is, force the bit alignment + * to 16-12 = 4 before putting out the EOL code. + */ + int align = 8 - 4; + if (align != sp->bit) + { + if (align > sp->bit) + align = sp->bit + (8 - align); + else + align = sp->bit - align; + tparm = align; + _PutBits(tif, 0, tparm); + } + } + code = EOL; + length = 12; + if (is2DEncoding(sp)) + { + code = (code << 1) | (sp->tag == G3_1D); + length++; + } + _PutBits(tif, code, length); + + sp->data = data; + sp->bit = bit; + + return 1; } /* * Reset encoding state at the start of a strip. */ -static int -Fax3PreEncode(TIFF* tif, uint16_t s) +static int Fax3PreEncode(TIFF *tif, uint16_t s) { - Fax3CodecState* sp = EncoderState(tif); - - (void) s; - assert(sp != NULL); - sp->bit = 8; - sp->data = 0; - sp->tag = G3_1D; - /* - * This is necessary for Group 4; otherwise it isn't - * needed because the first scanline of each strip ends - * up being copied into the refline. - */ - if (sp->refline) - _TIFFmemset(sp->refline, 0x00, sp->b.rowbytes); - if (is2DEncoding(sp)) { - float res = tif->tif_dir.td_yresolution; - /* - * The CCITT spec says that when doing 2d encoding, you - * should only do it on K consecutive scanlines, where K - * depends on the resolution of the image being encoded - * (2 for <= 200 lpi, 4 for > 200 lpi). Since the directory - * code initializes td_yresolution to 0, this code will - * select a K of 2 unless the YResolution tag is set - * appropriately. (Note also that we fudge a little here - * and use 150 lpi to avoid problems with units conversion.) - */ - if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER) - res *= 2.54f; /* convert to inches */ - sp->maxk = (res > 150 ? 4 : 2); - sp->k = sp->maxk-1; - } else - sp->k = sp->maxk = 0; - sp->line = 0; - return (1); + Fax3CodecState *sp = EncoderState(tif); + + (void)s; + assert(sp != NULL); + sp->bit = 8; + sp->data = 0; + sp->tag = G3_1D; + /* + * This is necessary for Group 4; otherwise it isn't + * needed because the first scanline of each strip ends + * up being copied into the refline. + */ + if (sp->refline) + _TIFFmemset(sp->refline, 0x00, sp->b.rowbytes); + if (is2DEncoding(sp)) + { + float res = tif->tif_dir.td_yresolution; + /* + * The CCITT spec says that when doing 2d encoding, you + * should only do it on K consecutive scanlines, where K + * depends on the resolution of the image being encoded + * (2 for <= 200 lpi, 4 for > 200 lpi). Since the directory + * code initializes td_yresolution to 0, this code will + * select a K of 2 unless the YResolution tag is set + * appropriately. (Note also that we fudge a little here + * and use 150 lpi to avoid problems with units conversion.) + */ + if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER) + res *= 2.54f; /* convert to inches */ + sp->maxk = (res > 150 ? 4 : 2); + sp->k = sp->maxk - 1; + } + else + sp->k = sp->maxk = 0; + sp->line = 0; + return (1); } static const unsigned char zeroruns[256] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */ + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */ }; static const unsigned char oneruns[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */ - 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */ + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */ }; /* @@ -797,128 +850,141 @@ static const unsigned char oneruns[256] = { * table. The ``base'' of the bit string is supplied * along with the start+end bit indices. */ -static inline int32_t -find0span(unsigned char* bp, int32_t bs, int32_t be) +static inline int32_t find0span(unsigned char *bp, int32_t bs, int32_t be) { - int32_t bits = be - bs; - int32_t n, span; - - bp += bs>>3; - /* - * Check partial byte on lhs. - */ - if (bits > 0 && (n = (bs & 7)) != 0) { - span = zeroruns[(*bp << n) & 0xff]; - if (span > 8-n) /* table value too generous */ - span = 8-n; - if (span > bits) /* constrain span to bit range */ - span = bits; - if (n+span < 8) /* doesn't extend to edge of byte */ - return (span); - bits -= span; - bp++; - } else - span = 0; - if (bits >= (int32_t)(2 * 8 * sizeof(int64_t))) { - int64_t* lp; - /* - * Align to int64_t boundary and check int64_t words. - */ - while (!isAligned(bp, int64_t)) { - if (*bp != 0x00) - return (span + zeroruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - lp = (int64_t*) bp; - while ((bits >= (int32_t)(8 * sizeof(int64_t))) && (0 == *lp)) { - span += 8*sizeof (int64_t); - bits -= 8*sizeof (int64_t); - lp++; - } - bp = (unsigned char*) lp; - } - /* - * Scan full bytes for all 0's. - */ - while (bits >= 8) { - if (*bp != 0x00) /* end of run */ - return (span + zeroruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - /* - * Check partial byte on rhs. - */ - if (bits > 0) { - n = zeroruns[*bp]; - span += (n > bits ? bits : n); - } - return (span); + int32_t bits = be - bs; + int32_t n, span; + + bp += bs >> 3; + /* + * Check partial byte on lhs. + */ + if (bits > 0 && (n = (bs & 7)) != 0) + { + span = zeroruns[(*bp << n) & 0xff]; + if (span > 8 - n) /* table value too generous */ + span = 8 - n; + if (span > bits) /* constrain span to bit range */ + span = bits; + if (n + span < 8) /* doesn't extend to edge of byte */ + return (span); + bits -= span; + bp++; + } + else + span = 0; + if (bits >= (int32_t)(2 * 8 * sizeof(int64_t))) + { + int64_t *lp; + /* + * Align to int64_t boundary and check int64_t words. + */ + while (!isAligned(bp, int64_t)) + { + if (*bp != 0x00) + return (span + zeroruns[*bp]); + span += 8; + bits -= 8; + bp++; + } + lp = (int64_t *)bp; + while ((bits >= (int32_t)(8 * sizeof(int64_t))) && (0 == *lp)) + { + span += 8 * sizeof(int64_t); + bits -= 8 * sizeof(int64_t); + lp++; + } + bp = (unsigned char *)lp; + } + /* + * Scan full bytes for all 0's. + */ + while (bits >= 8) + { + if (*bp != 0x00) /* end of run */ + return (span + zeroruns[*bp]); + span += 8; + bits -= 8; + bp++; + } + /* + * Check partial byte on rhs. + */ + if (bits > 0) + { + n = zeroruns[*bp]; + span += (n > bits ? bits : n); + } + return (span); } -static inline int32_t -find1span(unsigned char* bp, int32_t bs, int32_t be) +static inline int32_t find1span(unsigned char *bp, int32_t bs, int32_t be) { - int32_t bits = be - bs; - int32_t n, span; - - bp += bs>>3; - /* - * Check partial byte on lhs. - */ - if (bits > 0 && (n = (bs & 7)) != 0) { - span = oneruns[(*bp << n) & 0xff]; - if (span > 8-n) /* table value too generous */ - span = 8-n; - if (span > bits) /* constrain span to bit range */ - span = bits; - if (n+span < 8) /* doesn't extend to edge of byte */ - return (span); - bits -= span; - bp++; - } else - span = 0; - if (bits >= (int32_t)(2 * 8 * sizeof(int64_t))) { - int64_t* lp; - /* - * Align to int64_t boundary and check int64_t words. - */ - while (!isAligned(bp, int64_t)) { - if (*bp != 0xff) - return (span + oneruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - lp = (int64_t*) bp; - while ((bits >= (int32_t)(8 * sizeof(int64_t))) && (~((uint64_t)0) == (uint64_t)*lp)) { - span += 8*sizeof (int64_t); - bits -= 8*sizeof (int64_t); - lp++; - } - bp = (unsigned char*) lp; - } - /* - * Scan full bytes for all 1's. - */ - while (bits >= 8) { - if (*bp != 0xff) /* end of run */ - return (span + oneruns[*bp]); - span += 8; - bits -= 8; - bp++; - } - /* - * Check partial byte on rhs. - */ - if (bits > 0) { - n = oneruns[*bp]; - span += (n > bits ? bits : n); - } - return (span); + int32_t bits = be - bs; + int32_t n, span; + + bp += bs >> 3; + /* + * Check partial byte on lhs. + */ + if (bits > 0 && (n = (bs & 7)) != 0) + { + span = oneruns[(*bp << n) & 0xff]; + if (span > 8 - n) /* table value too generous */ + span = 8 - n; + if (span > bits) /* constrain span to bit range */ + span = bits; + if (n + span < 8) /* doesn't extend to edge of byte */ + return (span); + bits -= span; + bp++; + } + else + span = 0; + if (bits >= (int32_t)(2 * 8 * sizeof(int64_t))) + { + int64_t *lp; + /* + * Align to int64_t boundary and check int64_t words. + */ + while (!isAligned(bp, int64_t)) + { + if (*bp != 0xff) + return (span + oneruns[*bp]); + span += 8; + bits -= 8; + bp++; + } + lp = (int64_t *)bp; + while ((bits >= (int32_t)(8 * sizeof(int64_t))) && + (~((uint64_t)0) == (uint64_t)*lp)) + { + span += 8 * sizeof(int64_t); + bits -= 8 * sizeof(int64_t); + lp++; + } + bp = (unsigned char *)lp; + } + /* + * Scan full bytes for all 1's. + */ + while (bits >= 8) + { + if (*bp != 0xff) /* end of run */ + return (span + oneruns[*bp]); + span += 8; + bits -= 8; + bp++; + } + /* + * Check partial byte on rhs. + */ + if (bits > 0) + { + n = oneruns[*bp]; + span += (n > bits ? bits : n); + } + return (span); } /* @@ -927,474 +993,501 @@ find1span(unsigned char* bp, int32_t bs, int32_t be) * color. The end, be, is returned if no such bit * exists. */ -#define finddiff(_cp, _bs, _be, _color) \ - (_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be))) +#define finddiff(_cp, _bs, _be, _color) \ + (_bs + (_color ? find1span(_cp, _bs, _be) : find0span(_cp, _bs, _be))) /* * Like finddiff, but also check the starting bit * against the end in case start > end. */ -#define finddiff2(_cp, _bs, _be, _color) \ - (_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be) +#define finddiff2(_cp, _bs, _be, _color) \ + (_bs < _be ? finddiff(_cp, _bs, _be, _color) : _be) /* * 1d-encode a row of pixels. The encoding is * a sequence of all-white or all-black spans * of pixels encoded with Huffman codes. */ -static int -Fax3Encode1DRow(TIFF* tif, unsigned char* bp, uint32_t bits) +static int Fax3Encode1DRow(TIFF *tif, unsigned char *bp, uint32_t bits) { - Fax3CodecState* sp = EncoderState(tif); - int32_t span; - uint32_t bs = 0; - - for (;;) { - span = find0span(bp, bs, bits); /* white span */ - if( !putspan(tif, span, TIFFFaxWhiteCodes) ) - return 0; - bs += span; - if (bs >= bits) - break; - span = find1span(bp, bs, bits); /* black span */ - if( !putspan(tif, span, TIFFFaxBlackCodes) ) - return 0; - bs += span; - if (bs >= bits) - break; - } - if (sp->b.mode & (FAXMODE_BYTEALIGN|FAXMODE_WORDALIGN)) { - if (sp->bit != 8) /* byte-align */ - Fax3FlushBits(tif, sp); - if ((sp->b.mode&FAXMODE_WORDALIGN) && - !isAligned(tif->tif_rawcp, uint16_t)) - Fax3FlushBits(tif, sp); - } - return (1); + Fax3CodecState *sp = EncoderState(tif); + int32_t span; + uint32_t bs = 0; + + for (;;) + { + span = find0span(bp, bs, bits); /* white span */ + if (!putspan(tif, span, TIFFFaxWhiteCodes)) + return 0; + bs += span; + if (bs >= bits) + break; + span = find1span(bp, bs, bits); /* black span */ + if (!putspan(tif, span, TIFFFaxBlackCodes)) + return 0; + bs += span; + if (bs >= bits) + break; + } + if (sp->b.mode & (FAXMODE_BYTEALIGN | FAXMODE_WORDALIGN)) + { + if (sp->bit != 8) /* byte-align */ + Fax3FlushBits(tif, sp); + if ((sp->b.mode & FAXMODE_WORDALIGN) && + !isAligned(tif->tif_rawcp, uint16_t)) + Fax3FlushBits(tif, sp); + } + return (1); } -static const tableentry horizcode = - { 3, 0x1, 0 }; /* 001 */ -static const tableentry passcode = - { 4, 0x1, 0 }; /* 0001 */ +static const tableentry horizcode = {3, 0x1, 0}; /* 001 */ +static const tableentry passcode = {4, 0x1, 0}; /* 0001 */ static const tableentry vcodes[7] = { - { 7, 0x03, 0 }, /* 0000 011 */ - { 6, 0x03, 0 }, /* 0000 11 */ - { 3, 0x03, 0 }, /* 011 */ - { 1, 0x1, 0 }, /* 1 */ - { 3, 0x2, 0 }, /* 010 */ - { 6, 0x02, 0 }, /* 0000 10 */ - { 7, 0x02, 0 } /* 0000 010 */ + {7, 0x03, 0}, /* 0000 011 */ + {6, 0x03, 0}, /* 0000 11 */ + {3, 0x03, 0}, /* 011 */ + {1, 0x1, 0}, /* 1 */ + {3, 0x2, 0}, /* 010 */ + {6, 0x02, 0}, /* 0000 10 */ + {7, 0x02, 0} /* 0000 010 */ }; /* * 2d-encode a row of pixels. Consult the CCITT * documentation for the algorithm. */ -static int -Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32_t bits) +static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp, + uint32_t bits) { -#define PIXEL(buf,ix) ((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1) - uint32_t a0 = 0; - uint32_t a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0)); - uint32_t b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0)); - uint32_t a2, b2; - - for (;;) { - b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1)); - if (b2 >= a1) { - /* Naive computation triggers -fsanitize=undefined,unsigned-integer-overflow */ - /* although it is correct unless the difference between both is < 31 bit */ - /* int32_t d = b1 - a1; */ - int32_t d = (b1 >= a1 && b1 - a1 <= 3U) ? (int32_t)(b1 - a1) : - (b1 < a1 && a1 - b1 <= 3U) ? -(int32_t)(a1 - b1) : 0x7FFFFFFF; - if (!(-3 <= d && d <= 3)) { /* horizontal mode */ - a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1)); - if( !putcode(tif, &horizcode) ) - return 0; - if (a0+a1 == 0 || PIXEL(bp, a0) == 0) { - if( !putspan(tif, a1-a0, TIFFFaxWhiteCodes) ) - return 0; - if( !putspan(tif, a2-a1, TIFFFaxBlackCodes) ) - return 0; - } else { - if( !putspan(tif, a1-a0, TIFFFaxBlackCodes) ) - return 0; - if( !putspan(tif, a2-a1, TIFFFaxWhiteCodes) ) - return 0; - } - a0 = a2; - } else { /* vertical mode */ - if( !putcode(tif, &vcodes[d+3]) ) - return 0; - a0 = a1; - } - } else { /* pass mode */ - if( !putcode(tif, &passcode) ) - return 0; - a0 = b2; - } - if (a0 >= bits) - break; - a1 = finddiff(bp, a0, bits, PIXEL(bp,a0)); - b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0)); - b1 = finddiff(rp, b1, bits, PIXEL(bp,a0)); - } - return (1); +#define PIXEL(buf, ix) ((((buf)[(ix) >> 3]) >> (7 - ((ix)&7))) & 1) + uint32_t a0 = 0; + uint32_t a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0)); + uint32_t b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0)); + uint32_t a2, b2; + + for (;;) + { + b2 = finddiff2(rp, b1, bits, PIXEL(rp, b1)); + if (b2 >= a1) + { + /* Naive computation triggers + * -fsanitize=undefined,unsigned-integer-overflow */ + /* although it is correct unless the difference between both is < 31 + * bit */ + /* int32_t d = b1 - a1; */ + int32_t d = (b1 >= a1 && b1 - a1 <= 3U) ? (int32_t)(b1 - a1) + : (b1 < a1 && a1 - b1 <= 3U) ? -(int32_t)(a1 - b1) + : 0x7FFFFFFF; + if (!(-3 <= d && d <= 3)) + { /* horizontal mode */ + a2 = finddiff2(bp, a1, bits, PIXEL(bp, a1)); + if (!putcode(tif, &horizcode)) + return 0; + if (a0 + a1 == 0 || PIXEL(bp, a0) == 0) + { + if (!putspan(tif, a1 - a0, TIFFFaxWhiteCodes)) + return 0; + if (!putspan(tif, a2 - a1, TIFFFaxBlackCodes)) + return 0; + } + else + { + if (!putspan(tif, a1 - a0, TIFFFaxBlackCodes)) + return 0; + if (!putspan(tif, a2 - a1, TIFFFaxWhiteCodes)) + return 0; + } + a0 = a2; + } + else + { /* vertical mode */ + if (!putcode(tif, &vcodes[d + 3])) + return 0; + a0 = a1; + } + } + else + { /* pass mode */ + if (!putcode(tif, &passcode)) + return 0; + a0 = b2; + } + if (a0 >= bits) + break; + a1 = finddiff(bp, a0, bits, PIXEL(bp, a0)); + b1 = finddiff(rp, a0, bits, !PIXEL(bp, a0)); + b1 = finddiff(rp, b1, bits, PIXEL(bp, a0)); + } + return (1); #undef PIXEL } /* * Encode a buffer of pixels. */ -static int -Fax3Encode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int Fax3Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "Fax3Encode"; - Fax3CodecState* sp = EncoderState(tif); - (void) s; - if (cc % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written"); - return (0); - } - while (cc > 0) { - if ((sp->b.mode & FAXMODE_NOEOL) == 0) - { - if( !Fax3PutEOL(tif) ) - return 0; - } - if (is2DEncoding(sp)) { - if (sp->tag == G3_1D) { - if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) - return (0); - sp->tag = G3_2D; - } else { - if (!Fax3Encode2DRow(tif, bp, sp->refline, - sp->b.rowpixels)) - return (0); - sp->k--; - } - if (sp->k == 0) { - sp->tag = G3_1D; - sp->k = sp->maxk-1; - } else - _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); - } else { - if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) - return (0); - } - bp += sp->b.rowbytes; - cc -= sp->b.rowbytes; - } - return (1); + static const char module[] = "Fax3Encode"; + Fax3CodecState *sp = EncoderState(tif); + (void)s; + if (cc % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written"); + return (0); + } + while (cc > 0) + { + if ((sp->b.mode & FAXMODE_NOEOL) == 0) + { + if (!Fax3PutEOL(tif)) + return 0; + } + if (is2DEncoding(sp)) + { + if (sp->tag == G3_1D) + { + if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) + return (0); + sp->tag = G3_2D; + } + else + { + if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) + return (0); + sp->k--; + } + if (sp->k == 0) + { + sp->tag = G3_1D; + sp->k = sp->maxk - 1; + } + else + _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); + } + else + { + if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels)) + return (0); + } + bp += sp->b.rowbytes; + cc -= sp->b.rowbytes; + } + return (1); } -static int -Fax3PostEncode(TIFF* tif) +static int Fax3PostEncode(TIFF *tif) { - Fax3CodecState* sp = EncoderState(tif); + Fax3CodecState *sp = EncoderState(tif); - if (sp->bit != 8) - Fax3FlushBits(tif, sp); - return (1); + if (sp->bit != 8) + Fax3FlushBits(tif, sp); + return (1); } -static int -_Fax3Close(TIFF* tif) +static int _Fax3Close(TIFF *tif) { - if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) { - Fax3CodecState* sp = EncoderState(tif); - unsigned int code = EOL; - unsigned int length = 12; - int i; - - if (is2DEncoding(sp)) { - code = (code<<1) | (sp->tag == G3_1D); - length++; - } - for (i = 0; i < 6; i++) - Fax3PutBits(tif, code, length); - Fax3FlushBits(tif, sp); - } - return 1; + if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp) + { + Fax3CodecState *sp = EncoderState(tif); + unsigned int code = EOL; + unsigned int length = 12; + int i; + + if (is2DEncoding(sp)) + { + code = (code << 1) | (sp->tag == G3_1D); + length++; + } + for (i = 0; i < 6; i++) + Fax3PutBits(tif, code, length); + Fax3FlushBits(tif, sp); + } + return 1; } -static void -Fax3Close(TIFF* tif) -{ - _Fax3Close(tif); -} +static void Fax3Close(TIFF *tif) { _Fax3Close(tif); } -static void -Fax3Cleanup(TIFF* tif) +static void Fax3Cleanup(TIFF *tif) { - Fax3CodecState* sp = DecoderState(tif); - - assert(sp != 0); + Fax3CodecState *sp = DecoderState(tif); + + assert(sp != 0); - tif->tif_tagmethods.vgetfield = sp->b.vgetparent; - tif->tif_tagmethods.vsetfield = sp->b.vsetparent; - tif->tif_tagmethods.printdir = sp->b.printdir; + tif->tif_tagmethods.vgetfield = sp->b.vgetparent; + tif->tif_tagmethods.vsetfield = sp->b.vsetparent; + tif->tif_tagmethods.printdir = sp->b.printdir; - if (sp->runs) - _TIFFfreeExt(tif, sp->runs); - if (sp->refline) - _TIFFfreeExt(tif, sp->refline); + if (sp->runs) + _TIFFfreeExt(tif, sp->runs); + if (sp->refline) + _TIFFfreeExt(tif, sp->refline); - _TIFFfreeExt(tif, tif->tif_data); - tif->tif_data = NULL; + _TIFFfreeExt(tif, tif->tif_data); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } -#define FIELD_BADFAXLINES (FIELD_CODEC+0) -#define FIELD_CLEANFAXDATA (FIELD_CODEC+1) -#define FIELD_BADFAXRUN (FIELD_CODEC+2) +#define FIELD_BADFAXLINES (FIELD_CODEC + 0) +#define FIELD_CLEANFAXDATA (FIELD_CODEC + 1) +#define FIELD_BADFAXRUN (FIELD_CODEC + 2) -#define FIELD_OPTIONS (FIELD_CODEC+7) +#define FIELD_OPTIONS (FIELD_CODEC + 7) static const TIFFField faxFields[] = { - { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL }, - { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL }, - { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL }, - { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL }, - { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", NULL }}; + {TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, + FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL}, + {TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL}, + {TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL}, + {TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL}, + {TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", + NULL}}; static const TIFFField fax3Fields[] = { - { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL }, + {TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL}, }; static const TIFFField fax4Fields[] = { - { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL }, + {TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL}, }; -static int -Fax3VSetField(TIFF* tif, uint32_t tag, va_list ap) +static int Fax3VSetField(TIFF *tif, uint32_t tag, va_list ap) { - Fax3BaseState* sp = Fax3State(tif); - const TIFFField* fip; - - assert(sp != 0); - assert(sp->vsetparent != 0); - - switch (tag) { - case TIFFTAG_FAXMODE: - sp->mode = (int) va_arg(ap, int); - return 1; /* NB: pseudo tag */ - case TIFFTAG_FAXFILLFUNC: - DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); - return 1; /* NB: pseudo tag */ - case TIFFTAG_GROUP3OPTIONS: - /* XXX: avoid reading options if compression mismatches. */ - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) - sp->groupoptions = (uint32_t) va_arg(ap, uint32_t); - break; - case TIFFTAG_GROUP4OPTIONS: - /* XXX: avoid reading options if compression mismatches. */ - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) - sp->groupoptions = (uint32_t) va_arg(ap, uint32_t); - break; - case TIFFTAG_BADFAXLINES: - sp->badfaxlines = (uint32_t) va_arg(ap, uint32_t); - break; - case TIFFTAG_CLEANFAXDATA: - sp->cleanfaxdata = (uint16_t) va_arg(ap, uint16_vap); - break; - case TIFFTAG_CONSECUTIVEBADFAXLINES: - sp->badfaxrun = (uint32_t) va_arg(ap, uint32_t); - break; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - - if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) - TIFFSetFieldBit(tif, fip->field_bit); - else - return 0; - - tif->tif_flags |= TIFF_DIRTYDIRECT; - return 1; + Fax3BaseState *sp = Fax3State(tif); + const TIFFField *fip; + + assert(sp != 0); + assert(sp->vsetparent != 0); + + switch (tag) + { + case TIFFTAG_FAXMODE: + sp->mode = (int)va_arg(ap, int); + return 1; /* NB: pseudo tag */ + case TIFFTAG_FAXFILLFUNC: + DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc); + return 1; /* NB: pseudo tag */ + case TIFFTAG_GROUP3OPTIONS: + /* XXX: avoid reading options if compression mismatches. */ + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3) + sp->groupoptions = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_GROUP4OPTIONS: + /* XXX: avoid reading options if compression mismatches. */ + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) + sp->groupoptions = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_BADFAXLINES: + sp->badfaxlines = (uint32_t)va_arg(ap, uint32_t); + break; + case TIFFTAG_CLEANFAXDATA: + sp->cleanfaxdata = (uint16_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_CONSECUTIVEBADFAXLINES: + sp->badfaxrun = (uint32_t)va_arg(ap, uint32_t); + break; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + + if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) + TIFFSetFieldBit(tif, fip->field_bit); + else + return 0; + + tif->tif_flags |= TIFF_DIRTYDIRECT; + return 1; } -static int -Fax3VGetField(TIFF* tif, uint32_t tag, va_list ap) +static int Fax3VGetField(TIFF *tif, uint32_t tag, va_list ap) { - Fax3BaseState* sp = Fax3State(tif); - - assert(sp != 0); - - switch (tag) { - case TIFFTAG_FAXMODE: - *va_arg(ap, int*) = sp->mode; - break; - case TIFFTAG_FAXFILLFUNC: - *va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill; - break; - case TIFFTAG_GROUP3OPTIONS: - case TIFFTAG_GROUP4OPTIONS: - *va_arg(ap, uint32_t*) = sp->groupoptions; - break; - case TIFFTAG_BADFAXLINES: - *va_arg(ap, uint32_t*) = sp->badfaxlines; - break; - case TIFFTAG_CLEANFAXDATA: - *va_arg(ap, uint16_t*) = sp->cleanfaxdata; - break; - case TIFFTAG_CONSECUTIVEBADFAXLINES: - *va_arg(ap, uint32_t*) = sp->badfaxrun; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return (1); + Fax3BaseState *sp = Fax3State(tif); + + assert(sp != 0); + + switch (tag) + { + case TIFFTAG_FAXMODE: + *va_arg(ap, int *) = sp->mode; + break; + case TIFFTAG_FAXFILLFUNC: + *va_arg(ap, TIFFFaxFillFunc *) = DecoderState(tif)->fill; + break; + case TIFFTAG_GROUP3OPTIONS: + case TIFFTAG_GROUP4OPTIONS: + *va_arg(ap, uint32_t *) = sp->groupoptions; + break; + case TIFFTAG_BADFAXLINES: + *va_arg(ap, uint32_t *) = sp->badfaxlines; + break; + case TIFFTAG_CLEANFAXDATA: + *va_arg(ap, uint16_t *) = sp->cleanfaxdata; + break; + case TIFFTAG_CONSECUTIVEBADFAXLINES: + *va_arg(ap, uint32_t *) = sp->badfaxrun; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); } -static void -Fax3PrintDir(TIFF* tif, FILE* fd, long flags) +static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags) { - Fax3BaseState* sp = Fax3State(tif); - - assert(sp != 0); - - (void) flags; - if (TIFFFieldSet(tif,FIELD_OPTIONS)) { - const char* sep = " "; - if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) { - fprintf(fd, " Group 4 Options:"); - if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED) - fprintf(fd, "%suncompressed data", sep); - } else { - - fprintf(fd, " Group 3 Options:"); - if (sp->groupoptions & GROUP3OPT_2DENCODING) { - fprintf(fd, "%s2-d encoding", sep); - sep = "+"; - } - if (sp->groupoptions & GROUP3OPT_FILLBITS) { - fprintf(fd, "%sEOL padding", sep); - sep = "+"; - } - if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED) - fprintf(fd, "%suncompressed data", sep); - } - fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", - sp->groupoptions, - sp->groupoptions); - } - if (TIFFFieldSet(tif,FIELD_CLEANFAXDATA)) { - fprintf(fd, " Fax Data:"); - switch (sp->cleanfaxdata) { - case CLEANFAXDATA_CLEAN: - fprintf(fd, " clean"); - break; - case CLEANFAXDATA_REGENERATED: - fprintf(fd, " receiver regenerated"); - break; - case CLEANFAXDATA_UNCLEAN: - fprintf(fd, " uncorrected errors"); - break; - } - fprintf(fd, " (%"PRIu16" = 0x%"PRIx16")\n", - sp->cleanfaxdata, sp->cleanfaxdata); - } - if (TIFFFieldSet(tif,FIELD_BADFAXLINES)) - fprintf(fd, " Bad Fax Lines: %" PRIu32 "\n", - sp->badfaxlines); - if (TIFFFieldSet(tif,FIELD_BADFAXRUN)) - fprintf(fd, " Consecutive Bad Fax Lines: %" PRIu32 "\n", - sp->badfaxrun); - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); + Fax3BaseState *sp = Fax3State(tif); + + assert(sp != 0); + + (void)flags; + if (TIFFFieldSet(tif, FIELD_OPTIONS)) + { + const char *sep = " "; + if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) + { + fprintf(fd, " Group 4 Options:"); + if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED) + fprintf(fd, "%suncompressed data", sep); + } + else + { + + fprintf(fd, " Group 3 Options:"); + if (sp->groupoptions & GROUP3OPT_2DENCODING) + { + fprintf(fd, "%s2-d encoding", sep); + sep = "+"; + } + if (sp->groupoptions & GROUP3OPT_FILLBITS) + { + fprintf(fd, "%sEOL padding", sep); + sep = "+"; + } + if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED) + fprintf(fd, "%suncompressed data", sep); + } + fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", sp->groupoptions, + sp->groupoptions); + } + if (TIFFFieldSet(tif, FIELD_CLEANFAXDATA)) + { + fprintf(fd, " Fax Data:"); + switch (sp->cleanfaxdata) + { + case CLEANFAXDATA_CLEAN: + fprintf(fd, " clean"); + break; + case CLEANFAXDATA_REGENERATED: + fprintf(fd, " receiver regenerated"); + break; + case CLEANFAXDATA_UNCLEAN: + fprintf(fd, " uncorrected errors"); + break; + } + fprintf(fd, " (%" PRIu16 " = 0x%" PRIx16 ")\n", sp->cleanfaxdata, + sp->cleanfaxdata); + } + if (TIFFFieldSet(tif, FIELD_BADFAXLINES)) + fprintf(fd, " Bad Fax Lines: %" PRIu32 "\n", sp->badfaxlines); + if (TIFFFieldSet(tif, FIELD_BADFAXRUN)) + fprintf(fd, " Consecutive Bad Fax Lines: %" PRIu32 "\n", + sp->badfaxrun); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); } -static int -InitCCITTFax3(TIFF* tif) +static int InitCCITTFax3(TIFF *tif) { - static const char module[] = "InitCCITTFax3"; - Fax3BaseState* sp; - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) { - TIFFErrorExtR(tif, "InitCCITTFax3", - "Merging common CCITT Fax codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t*) - _TIFFmallocExt(tif, sizeof (Fax3CodecState)); - - if (tif->tif_data == NULL) { - TIFFErrorExtR(tif, module, - "No space for state block"); - return (0); - } - _TIFFmemset(tif->tif_data, 0, sizeof (Fax3CodecState)); - - sp = Fax3State(tif); - sp->rw_mode = tif->tif_mode; - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */ - sp->printdir = tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */ - sp->groupoptions = 0; - - if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */ - tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */ - DecoderState(tif)->runs = NULL; - TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns); - EncoderState(tif)->refline = NULL; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = Fax3FixupTags; - tif->tif_setupdecode = Fax3SetupState; - tif->tif_predecode = Fax3PreDecode; - tif->tif_decoderow = Fax3Decode1D; - tif->tif_decodestrip = Fax3Decode1D; - tif->tif_decodetile = Fax3Decode1D; - tif->tif_setupencode = Fax3SetupState; - tif->tif_preencode = Fax3PreEncode; - tif->tif_postencode = Fax3PostEncode; - tif->tif_encoderow = Fax3Encode; - tif->tif_encodestrip = Fax3Encode; - tif->tif_encodetile = Fax3Encode; - tif->tif_close = Fax3Close; - tif->tif_cleanup = Fax3Cleanup; - - return (1); + static const char module[] = "InitCCITTFax3"; + Fax3BaseState *sp; + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) + { + TIFFErrorExtR(tif, "InitCCITTFax3", + "Merging common CCITT Fax codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(Fax3CodecState)); + + if (tif->tif_data == NULL) + { + TIFFErrorExtR(tif, module, "No space for state block"); + return (0); + } + _TIFFmemset(tif->tif_data, 0, sizeof(Fax3CodecState)); + + sp = Fax3State(tif); + sp->rw_mode = tif->tif_mode; + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */ + sp->printdir = tif->tif_tagmethods.printdir; + tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */ + sp->groupoptions = 0; + + if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */ + tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */ + DecoderState(tif)->runs = NULL; + TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns); + EncoderState(tif)->refline = NULL; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = Fax3FixupTags; + tif->tif_setupdecode = Fax3SetupState; + tif->tif_predecode = Fax3PreDecode; + tif->tif_decoderow = Fax3Decode1D; + tif->tif_decodestrip = Fax3Decode1D; + tif->tif_decodetile = Fax3Decode1D; + tif->tif_setupencode = Fax3SetupState; + tif->tif_preencode = Fax3PreEncode; + tif->tif_postencode = Fax3PostEncode; + tif->tif_encoderow = Fax3Encode; + tif->tif_encodestrip = Fax3Encode; + tif->tif_encodetile = Fax3Encode; + tif->tif_close = Fax3Close; + tif->tif_cleanup = Fax3Cleanup; + + return (1); } -int -TIFFInitCCITTFax3(TIFF* tif, int scheme) +int TIFFInitCCITTFax3(TIFF *tif, int scheme) { - (void) scheme; - if (InitCCITTFax3(tif)) { - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, fax3Fields, - TIFFArrayCount(fax3Fields))) { - TIFFErrorExtR(tif, "TIFFInitCCITTFax3", - "Merging CCITT Fax 3 codec-specific tags failed"); - return 0; - } - - /* - * The default format is Class/F-style w/o RTC. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF); - } else - return 01; + (void)scheme; + if (InitCCITTFax3(tif)) + { + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, fax3Fields, TIFFArrayCount(fax3Fields))) + { + TIFFErrorExtR(tif, "TIFFInitCCITTFax3", + "Merging CCITT Fax 3 codec-specific tags failed"); + return 0; + } + + /* + * The default format is Class/F-style w/o RTC. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF); + } + else + return 01; } /* @@ -1402,138 +1495,146 @@ TIFFInitCCITTFax3(TIFF* tif, int scheme) * Compression Scheme Support. */ -#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; } +#define SWAP(t, a, b) \ + { \ + t x; \ + x = (a); \ + (a) = (b); \ + (b) = x; \ + } /* * Decode the requested amount of G4-encoded data. */ -static int -Fax4Decode(TIFF* tif, uint8_t* buf, tmsize_t occ, uint16_t s) +static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - DECLARE_STATE_2D(tif, sp, "Fax4Decode"); - (void) s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - while (occ > 0) { - a0 = 0; - RunLength = 0; - pa = thisrun = sp->curruns; - pb = sp->refruns; - b1 = *pb++; + DECLARE_STATE_2D(tif, sp, "Fax4Decode"); + (void)s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + while (occ > 0) + { + a0 = 0; + RunLength = 0; + pa = thisrun = sp->curruns; + pb = sp->refruns; + b1 = *pb++; #ifdef FAX3_DEBUG - printf("\nBitAcc=%08"PRIX32", BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %d\n", tif->tif_row); - fflush(stdout); + printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %d\n", tif->tif_row); + fflush(stdout); #endif - EXPAND2D(EOFG4); - if (EOLcnt) - goto EOFG4; - if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ - { - TIFFErrorExtR(tif, module, - "Buffer overrun detected : %"TIFF_SSIZE_FORMAT" bytes available, %d bits needed", - occ, lastx); - return -1; - } - (*sp->fill)(buf, thisrun, pa, lastx); - SETVALUE(0); /* imaginary change for reference */ - SWAP(uint32_t*, sp->curruns, sp->refruns); - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOFG4: - NeedBits16( 13, BADG4 ); - BADG4: + EXPAND2D(EOFG4); + if (EOLcnt) + goto EOFG4; + if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ + { + TIFFErrorExtR(tif, module, + "Buffer overrun detected : %" TIFF_SSIZE_FORMAT + " bytes available, %d bits needed", + occ, lastx); + return -1; + } + (*sp->fill)(buf, thisrun, pa, lastx); + SETVALUE(0); /* imaginary change for reference */ + SWAP(uint32_t *, sp->curruns, sp->refruns); + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOFG4: + NeedBits16(13, BADG4); + BADG4: #ifdef FAX3_DEBUG - if( GetBits(13) != 0x1001 ) - fputs( "Bad EOFB\n", stderr ); -#endif - ClrBits( 13 ); - if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ - { - TIFFErrorExtR(tif, module, - "Buffer overrun detected : %"TIFF_SSIZE_FORMAT" bytes available, %d bits needed", - occ, lastx); - return -1; - } - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return ( sp->line ? 1 : -1); /* don't error on badly-terminated strips */ - } - UNCACHE_STATE(tif, sp); - return (1); + if (GetBits(13) != 0x1001) + fputs("Bad EOFB\n", stderr); +#endif + ClrBits(13); + if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */ + { + TIFFErrorExtR(tif, module, + "Buffer overrun detected : %" TIFF_SSIZE_FORMAT + " bytes available, %d bits needed", + occ, lastx); + return -1; + } + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (sp->line ? 1 : -1); /* don't error on badly-terminated strips */ + } + UNCACHE_STATE(tif, sp); + return (1); } -#undef SWAP +#undef SWAP /* * Encode the requested amount of data. */ -static int -Fax4Encode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int Fax4Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "Fax4Encode"; - Fax3CodecState *sp = EncoderState(tif); - (void) s; - if (cc % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written"); - return (0); - } - while (cc > 0) { - if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) - return (0); - _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); - bp += sp->b.rowbytes; - cc -= sp->b.rowbytes; - } - return (1); + static const char module[] = "Fax4Encode"; + Fax3CodecState *sp = EncoderState(tif); + (void)s; + if (cc % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written"); + return (0); + } + while (cc > 0) + { + if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels)) + return (0); + _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes); + bp += sp->b.rowbytes; + cc -= sp->b.rowbytes; + } + return (1); } -static int -Fax4PostEncode(TIFF* tif) +static int Fax4PostEncode(TIFF *tif) { - Fax3CodecState *sp = EncoderState(tif); - - /* terminate strip w/ EOFB */ - Fax3PutBits(tif, EOL, 12); - Fax3PutBits(tif, EOL, 12); - if (sp->bit != 8) - Fax3FlushBits(tif, sp); - return (1); + Fax3CodecState *sp = EncoderState(tif); + + /* terminate strip w/ EOFB */ + Fax3PutBits(tif, EOL, 12); + Fax3PutBits(tif, EOL, 12); + if (sp->bit != 8) + Fax3FlushBits(tif, sp); + return (1); } -int -TIFFInitCCITTFax4(TIFF* tif, int scheme) +int TIFFInitCCITTFax4(TIFF *tif, int scheme) { - (void) scheme; - if (InitCCITTFax3(tif)) { /* reuse G3 support */ - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, fax4Fields, - TIFFArrayCount(fax4Fields))) { - TIFFErrorExtR(tif, "TIFFInitCCITTFax4", - "Merging CCITT Fax 4 codec-specific tags failed"); - return 0; - } - - tif->tif_decoderow = Fax4Decode; - tif->tif_decodestrip = Fax4Decode; - tif->tif_decodetile = Fax4Decode; - tif->tif_encoderow = Fax4Encode; - tif->tif_encodestrip = Fax4Encode; - tif->tif_encodetile = Fax4Encode; - tif->tif_postencode = Fax4PostEncode; - /* - * Suppress RTC at the end of each strip. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC); - } else - return (0); + (void)scheme; + if (InitCCITTFax3(tif)) + { /* reuse G3 support */ + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, fax4Fields, TIFFArrayCount(fax4Fields))) + { + TIFFErrorExtR(tif, "TIFFInitCCITTFax4", + "Merging CCITT Fax 4 codec-specific tags failed"); + return 0; + } + + tif->tif_decoderow = Fax4Decode; + tif->tif_decodestrip = Fax4Decode; + tif->tif_decodetile = Fax4Decode; + tif->tif_encoderow = Fax4Encode; + tif->tif_encodestrip = Fax4Encode; + tif->tif_encodetile = Fax4Encode; + tif->tif_postencode = Fax4PostEncode; + /* + * Suppress RTC at the end of each strip. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC); + } + else + return (0); } /* @@ -1544,86 +1645,91 @@ TIFFInitCCITTFax4(TIFF* tif, int scheme) /* * Decode the requested amount of RLE-encoded data. */ -static int -Fax3DecodeRLE(TIFF* tif, uint8_t* buf, tmsize_t occ, uint16_t s) +static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - DECLARE_STATE(tif, sp, "Fax3DecodeRLE"); - int mode = sp->b.mode; - (void) s; - if (occ % sp->b.rowbytes) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (-1); - } - CACHE_STATE(tif, sp); - thisrun = sp->curruns; - while (occ > 0) { - a0 = 0; - RunLength = 0; - pa = thisrun; + DECLARE_STATE(tif, sp, "Fax3DecodeRLE"); + int mode = sp->b.mode; + (void)s; + if (occ % sp->b.rowbytes) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (-1); + } + CACHE_STATE(tif, sp); + thisrun = sp->curruns; + while (occ > 0) + { + a0 = 0; + RunLength = 0; + pa = thisrun; #ifdef FAX3_DEBUG - printf("\nBitAcc=%08"PRIX32", BitsAvail = %d\n", BitAcc, BitsAvail); - printf("-------------------- %"PRIu32"\n", tif->tif_row); - fflush(stdout); + printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail); + printf("-------------------- %" PRIu32 "\n", tif->tif_row); + fflush(stdout); #endif - EXPAND1D(EOFRLE); - (*sp->fill)(buf, thisrun, pa, lastx); - /* - * Cleanup at the end of the row. - */ - if (mode & FAXMODE_BYTEALIGN) { - int n = BitsAvail - (BitsAvail &~ 7); - ClrBits(n); - } else if (mode & FAXMODE_WORDALIGN) { - int n = BitsAvail - (BitsAvail &~ 15); - ClrBits(n); - if (BitsAvail == 0 && !isAligned(cp, uint16_t)) - cp++; - } - buf += sp->b.rowbytes; - occ -= sp->b.rowbytes; - sp->line++; - continue; - EOFRLE: /* premature EOF */ - (*sp->fill)(buf, thisrun, pa, lastx); - UNCACHE_STATE(tif, sp); - return (-1); - } - UNCACHE_STATE(tif, sp); - return (1); + EXPAND1D(EOFRLE); + (*sp->fill)(buf, thisrun, pa, lastx); + /* + * Cleanup at the end of the row. + */ + if (mode & FAXMODE_BYTEALIGN) + { + int n = BitsAvail - (BitsAvail & ~7); + ClrBits(n); + } + else if (mode & FAXMODE_WORDALIGN) + { + int n = BitsAvail - (BitsAvail & ~15); + ClrBits(n); + if (BitsAvail == 0 && !isAligned(cp, uint16_t)) + cp++; + } + buf += sp->b.rowbytes; + occ -= sp->b.rowbytes; + sp->line++; + continue; + EOFRLE: /* premature EOF */ + (*sp->fill)(buf, thisrun, pa, lastx); + UNCACHE_STATE(tif, sp); + return (-1); + } + UNCACHE_STATE(tif, sp); + return (1); } -int -TIFFInitCCITTRLE(TIFF* tif, int scheme) +int TIFFInitCCITTRLE(TIFF *tif, int scheme) { - (void) scheme; - if (InitCCITTFax3(tif)) { /* reuse G3 support */ - tif->tif_decoderow = Fax3DecodeRLE; - tif->tif_decodestrip = Fax3DecodeRLE; - tif->tif_decodetile = Fax3DecodeRLE; - /* - * Suppress RTC+EOLs when encoding and byte-align data. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, - FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_BYTEALIGN); - } else - return (0); + (void)scheme; + if (InitCCITTFax3(tif)) + { /* reuse G3 support */ + tif->tif_decoderow = Fax3DecodeRLE; + tif->tif_decodestrip = Fax3DecodeRLE; + tif->tif_decodetile = Fax3DecodeRLE; + /* + * Suppress RTC+EOLs when encoding and byte-align data. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, + FAXMODE_NORTC | FAXMODE_NOEOL | FAXMODE_BYTEALIGN); + } + else + return (0); } -int -TIFFInitCCITTRLEW(TIFF* tif, int scheme) +int TIFFInitCCITTRLEW(TIFF *tif, int scheme) { - (void) scheme; - if (InitCCITTFax3(tif)) { /* reuse G3 support */ - tif->tif_decoderow = Fax3DecodeRLE; - tif->tif_decodestrip = Fax3DecodeRLE; - tif->tif_decodetile = Fax3DecodeRLE; - /* - * Suppress RTC+EOLs when encoding and word-align data. - */ - return TIFFSetField(tif, TIFFTAG_FAXMODE, - FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_WORDALIGN); - } else - return (0); + (void)scheme; + if (InitCCITTFax3(tif)) + { /* reuse G3 support */ + tif->tif_decoderow = Fax3DecodeRLE; + tif->tif_decodestrip = Fax3DecodeRLE; + tif->tif_decodetile = Fax3DecodeRLE; + /* + * Suppress RTC+EOLs when encoding and word-align data. + */ + return TIFFSetField(tif, TIFFTAG_FAXMODE, + FAXMODE_NORTC | FAXMODE_NOEOL | FAXMODE_WORDALIGN); + } + else + return (0); } #endif /* CCITT_SUPPORT */ diff --git a/libtiff/tif_fax3.h b/libtiff/tif_fax3.h index cb860ad9..e095009b 100644 --- a/libtiff/tif_fax3.h +++ b/libtiff/tif_fax3.h @@ -2,28 +2,28 @@ * Copyright (c) 1990-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _FAX3_ -#define _FAX3_ +#define _FAX3_ /* * TIFF Library. * @@ -50,41 +50,47 @@ * data in the run array as needed (e.g. to append zero runs to bring * the count up to a nice multiple). */ -typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32_t*, uint32_t*, uint32_t); +typedef void (*TIFFFaxFillFunc)(unsigned char *, uint32_t *, uint32_t *, + uint32_t); /* * The default run filler; made external for other decoders. */ #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -extern void _TIFFFax3fillruns(unsigned char*, uint32_t*, uint32_t*, uint32_t); + extern void _TIFFFax3fillruns(unsigned char *, uint32_t *, uint32_t *, + uint32_t); #if defined(__cplusplus) } #endif - /* finite state machine codes */ -#define S_Null 0 -#define S_Pass 1 -#define S_Horiz 2 -#define S_V0 3 -#define S_VR 4 -#define S_VL 5 -#define S_Ext 6 -#define S_TermW 7 -#define S_TermB 8 -#define S_MakeUpW 9 -#define S_MakeUpB 10 -#define S_MakeUp 11 -#define S_EOL 12 +#define S_Null 0 +#define S_Pass 1 +#define S_Horiz 2 +#define S_V0 3 +#define S_VR 4 +#define S_VL 5 +#define S_Ext 6 +#define S_TermW 7 +#define S_TermB 8 +#define S_MakeUpW 9 +#define S_MakeUpB 10 +#define S_MakeUp 11 +#define S_EOL 12 -/* WARNING: do not change the layout of this structure as the HylaFAX software */ -/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 */ -typedef struct { /* state table entry */ - unsigned char State; /* see above */ - unsigned char Width; /* width of code in bits */ - uint32_t Param; /* unsigned 32-bit run length in bits (holds on 16 bit actually, but cannot be changed. See above warning) */ +/* WARNING: do not change the layout of this structure as the HylaFAX software + */ +/* really depends on it. See http://bugzilla.maptools.org/show_bug.cgi?id=2636 + */ +typedef struct +{ /* state table entry */ + unsigned char State; /* see above */ + unsigned char Width; /* width of code in bits */ + uint32_t Param; /* unsigned 32-bit run length in bits (holds on 16 bit + actually, but cannot be changed. See above warning) */ } TIFFFaxTabEnt; extern const TIFFFaxTabEnt TIFFFaxMainTable[]; @@ -108,7 +114,7 @@ extern const TIFFFaxTabEnt TIFFFaxBlackTable[]; */ #ifndef EndOfData -#define EndOfData() (cp >= ep) +#define EndOfData() (cp >= ep) #endif /* * Need <=8 or <=16 bits of input data. Unlike viewfax we @@ -134,121 +140,143 @@ extern const TIFFFaxTabEnt TIFFFaxBlackTable[]; * otherwise we should get the right answer. */ #ifndef NeedBits8 -#define NeedBits8(n,eoflab) do { \ - if (BitsAvail < (n)) { \ - if (EndOfData()) { \ - if (BitsAvail == 0) /* no valid bits */ \ - goto eoflab; \ - BitsAvail = (n); /* pad with zeros */ \ - } else { \ - BitAcc |= ((uint32_t) bitmap[*cp++])<<BitsAvail; \ - BitsAvail += 8; \ - } \ - } \ -} while (0) +#define NeedBits8(n, eoflab) \ + do \ + { \ + if (BitsAvail < (n)) \ + { \ + if (EndOfData()) \ + { \ + if (BitsAvail == 0) /* no valid bits */ \ + goto eoflab; \ + BitsAvail = (n); /* pad with zeros */ \ + } \ + else \ + { \ + BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \ + BitsAvail += 8; \ + } \ + } \ + } while (0) #endif #ifndef NeedBits16 -#define NeedBits16(n,eoflab) do { \ - if (BitsAvail < (n)) { \ - if (EndOfData()) { \ - if (BitsAvail == 0) /* no valid bits */ \ - goto eoflab; \ - BitsAvail = (n); /* pad with zeros */ \ - } else { \ - BitAcc |= ((uint32_t) bitmap[*cp++])<<BitsAvail; \ - if ((BitsAvail += 8) < (n)) { \ - if (EndOfData()) { \ - /* NB: we know BitsAvail is non-zero here */ \ - BitsAvail = (n); /* pad with zeros */ \ - } else { \ - BitAcc |= ((uint32_t) bitmap[*cp++])<<BitsAvail; \ - BitsAvail += 8; \ - } \ - } \ - } \ - } \ -} while (0) +#define NeedBits16(n, eoflab) \ + do \ + { \ + if (BitsAvail < (n)) \ + { \ + if (EndOfData()) \ + { \ + if (BitsAvail == 0) /* no valid bits */ \ + goto eoflab; \ + BitsAvail = (n); /* pad with zeros */ \ + } \ + else \ + { \ + BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \ + if ((BitsAvail += 8) < (n)) \ + { \ + if (EndOfData()) \ + { \ + /* NB: we know BitsAvail is non-zero here */ \ + BitsAvail = (n); /* pad with zeros */ \ + } \ + else \ + { \ + BitAcc |= ((uint32_t)bitmap[*cp++]) << BitsAvail; \ + BitsAvail += 8; \ + } \ + } \ + } \ + } \ + } while (0) #endif -#define GetBits(n) (BitAcc & ((1<<(n))-1)) -#define ClrBits(n) do { \ - BitsAvail -= (n); \ - BitAcc >>= (n); \ -} while (0) +#define GetBits(n) (BitAcc & ((1 << (n)) - 1)) +#define ClrBits(n) \ + do \ + { \ + BitsAvail -= (n); \ + BitAcc >>= (n); \ + } while (0) #ifdef FAX3_DEBUG -static const char* StateNames[] = { - "Null ", - "Pass ", - "Horiz ", - "V0 ", - "VR ", - "VL ", - "Ext ", - "TermW ", - "TermB ", - "MakeUpW", - "MakeUpB", - "MakeUp ", - "EOL ", +static const char *StateNames[] = { + "Null ", "Pass ", "Horiz ", "V0 ", "VR ", "VL ", "Ext ", + "TermW ", "TermB ", "MakeUpW", "MakeUpB", "MakeUp ", "EOL ", }; #define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0') -#define LOOKUP8(wid,tab,eoflab) do { \ - int t; \ - NeedBits8(wid,eoflab); \ - TabEnt = tab + GetBits(wid); \ - printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \ - StateNames[TabEnt->State], TabEnt->Param); \ - for (t = 0; t < TabEnt->Width; t++) \ - DEBUG_SHOW; \ - putchar('\n'); \ - fflush(stdout); \ - ClrBits(TabEnt->Width); \ -} while (0) -#define LOOKUP16(wid,tab,eoflab) do { \ - int t; \ - NeedBits16(wid,eoflab); \ - TabEnt = tab + GetBits(wid); \ - printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \ - StateNames[TabEnt->State], TabEnt->Param); \ - for (t = 0; t < TabEnt->Width; t++) \ - DEBUG_SHOW; \ - putchar('\n'); \ - fflush(stdout); \ - ClrBits(TabEnt->Width); \ -} while (0) +#define LOOKUP8(wid, tab, eoflab) \ + do \ + { \ + int t; \ + NeedBits8(wid, eoflab); \ + TabEnt = tab + GetBits(wid); \ + printf("%08lX/%d: %s%5d\t", (long)BitAcc, BitsAvail, \ + StateNames[TabEnt->State], TabEnt->Param); \ + for (t = 0; t < TabEnt->Width; t++) \ + DEBUG_SHOW; \ + putchar('\n'); \ + fflush(stdout); \ + ClrBits(TabEnt->Width); \ + } while (0) +#define LOOKUP16(wid, tab, eoflab) \ + do \ + { \ + int t; \ + NeedBits16(wid, eoflab); \ + TabEnt = tab + GetBits(wid); \ + printf("%08lX/%d: %s%5d\t", (long)BitAcc, BitsAvail, \ + StateNames[TabEnt->State], TabEnt->Param); \ + for (t = 0; t < TabEnt->Width; t++) \ + DEBUG_SHOW; \ + putchar('\n'); \ + fflush(stdout); \ + ClrBits(TabEnt->Width); \ + } while (0) -#define SETVALUE(x) do { \ - *pa++ = RunLength + (x); \ - printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \ - a0 += x; \ - RunLength = 0; \ -} while (0) +#define SETVALUE(x) \ + do \ + { \ + *pa++ = RunLength + (x); \ + printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \ + a0 += x; \ + RunLength = 0; \ + } while (0) #else -#define LOOKUP8(wid,tab,eoflab) do { \ - NeedBits8(wid,eoflab); \ - TabEnt = tab + GetBits(wid); \ - ClrBits(TabEnt->Width); \ -} while (0) -#define LOOKUP16(wid,tab,eoflab) do { \ - NeedBits16(wid,eoflab); \ - TabEnt = tab + GetBits(wid); \ - ClrBits(TabEnt->Width); \ -} while (0) +#define LOOKUP8(wid, tab, eoflab) \ + do \ + { \ + NeedBits8(wid, eoflab); \ + TabEnt = tab + GetBits(wid); \ + ClrBits(TabEnt->Width); \ + } while (0) +#define LOOKUP16(wid, tab, eoflab) \ + do \ + { \ + NeedBits16(wid, eoflab); \ + TabEnt = tab + GetBits(wid); \ + ClrBits(TabEnt->Width); \ + } while (0) /* * Append a run to the run length array for the * current row and reset decoding state. */ -#define SETVALUE(x) do { \ - if (pa >= thisrun + sp->nruns) { \ - TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - *pa++ = RunLength + (x); \ - a0 += (x); \ - RunLength = 0; \ -} while (0) +#define SETVALUE(x) \ + do \ + { \ + if (pa >= thisrun + sp->nruns) \ + { \ + TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \ + sp->line, isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile \ + : tif->tif_curstrip); \ + return (-1); \ + } \ + *pa++ = RunLength + (x); \ + a0 += (x); \ + RunLength = 0; \ + } while (0) #endif /* @@ -261,51 +289,62 @@ static const char* StateNames[] = { * is non-zero then we still need to scan for the final flag * bit that is part of the EOL code. */ -#define SYNC_EOL(eoflab) do { \ - if (EOLcnt == 0) { \ - for (;;) { \ - NeedBits16(11,eoflab); \ - if (GetBits(11) == 0) \ - break; \ - ClrBits(1); \ - } \ - } \ - for (;;) { \ - NeedBits8(8,eoflab); \ - if (GetBits(8)) \ - break; \ - ClrBits(8); \ - } \ - while (GetBits(1) == 0) \ - ClrBits(1); \ - ClrBits(1); /* EOL bit */ \ - EOLcnt = 0; /* reset EOL counter/flag */ \ -} while (0) +#define SYNC_EOL(eoflab) \ + do \ + { \ + if (EOLcnt == 0) \ + { \ + for (;;) \ + { \ + NeedBits16(11, eoflab); \ + if (GetBits(11) == 0) \ + break; \ + ClrBits(1); \ + } \ + } \ + for (;;) \ + { \ + NeedBits8(8, eoflab); \ + if (GetBits(8)) \ + break; \ + ClrBits(8); \ + } \ + while (GetBits(1) == 0) \ + ClrBits(1); \ + ClrBits(1); /* EOL bit */ \ + EOLcnt = 0; /* reset EOL counter/flag */ \ + } while (0) /* * Cleanup the array of runs after decoding a row. * We adjust final runs to insure the user buffer is not * overwritten and/or undecoded area is white filled. */ -#define CLEANUP_RUNS() do { \ - if (RunLength) \ - SETVALUE(0); \ - if (a0 != lastx) { \ - badlength(a0, lastx); \ - while (a0 > lastx && pa > thisrun) \ - a0 -= *--pa; \ - if (a0 < lastx) { \ - if (a0 < 0) \ - a0 = 0; \ - if ((pa-thisrun)&1) \ - SETVALUE(0); \ - SETVALUE(lastx - a0); \ - } else if (a0 > lastx) { \ - SETVALUE(lastx); \ - SETVALUE(0); \ - } \ - } \ -} while (0) +#define CLEANUP_RUNS() \ + do \ + { \ + if (RunLength) \ + SETVALUE(0); \ + if (a0 != lastx) \ + { \ + badlength(a0, lastx); \ + while (a0 > lastx && pa > thisrun) \ + a0 -= *--pa; \ + if (a0 < lastx) \ + { \ + if (a0 < 0) \ + a0 = 0; \ + if ((pa - thisrun) & 1) \ + SETVALUE(0); \ + SETVALUE(lastx - a0); \ + } \ + else if (a0 > lastx) \ + { \ + SETVALUE(lastx); \ + SETVALUE(0); \ + } \ + } \ + } while (0) /* * Decode a line of 1D-encoded data. @@ -319,241 +358,291 @@ static const char* StateNames[] = { * the original code depended on the input data being zero-padded to * insure the decoder recognized an EOL before running out of data. */ -#define EXPAND1D(eoflab) do { \ - for (;;) { \ - for (;;) { \ - LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \ - switch (TabEnt->State) { \ - case S_EOL: \ - EOLcnt = 1; \ - goto done1d; \ - case S_TermW: \ - SETVALUE(TabEnt->Param); \ - goto doneWhite1d; \ - case S_MakeUpW: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - unexpected("WhiteTable", a0); \ - goto done1d; \ - } \ - } \ - doneWhite1d: \ - if (a0 >= lastx) \ - goto done1d; \ - for (;;) { \ - LOOKUP16(13, TIFFFaxBlackTable, eof1d); \ - switch (TabEnt->State) { \ - case S_EOL: \ - EOLcnt = 1; \ - goto done1d; \ - case S_TermB: \ - SETVALUE(TabEnt->Param); \ - goto doneBlack1d; \ - case S_MakeUpB: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - unexpected("BlackTable", a0); \ - goto done1d; \ - } \ - } \ - doneBlack1d: \ - if (a0 >= lastx) \ - goto done1d; \ - if( *(pa-1) == 0 && *(pa-2) == 0 ) \ - pa -= 2; \ - } \ -eof1d: \ - prematureEOF(a0); \ - CLEANUP_RUNS(); \ - goto eoflab; \ -done1d: \ - CLEANUP_RUNS(); \ -} while (0) +#define EXPAND1D(eoflab) \ + do \ + { \ + for (;;) \ + { \ + for (;;) \ + { \ + LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \ + switch (TabEnt->State) \ + { \ + case S_EOL: \ + EOLcnt = 1; \ + goto done1d; \ + case S_TermW: \ + SETVALUE(TabEnt->Param); \ + goto doneWhite1d; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("WhiteTable", a0); \ + goto done1d; \ + } \ + } \ + doneWhite1d: \ + if (a0 >= lastx) \ + goto done1d; \ + for (;;) \ + { \ + LOOKUP16(13, TIFFFaxBlackTable, eof1d); \ + switch (TabEnt->State) \ + { \ + case S_EOL: \ + EOLcnt = 1; \ + goto done1d; \ + case S_TermB: \ + SETVALUE(TabEnt->Param); \ + goto doneBlack1d; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + unexpected("BlackTable", a0); \ + goto done1d; \ + } \ + } \ + doneBlack1d: \ + if (a0 >= lastx) \ + goto done1d; \ + if (*(pa - 1) == 0 && *(pa - 2) == 0) \ + pa -= 2; \ + } \ + eof1d: \ + prematureEOF(a0); \ + CLEANUP_RUNS(); \ + goto eoflab; \ + done1d: \ + CLEANUP_RUNS(); \ + } while (0) /* * Update the value of b1 using the array * of runs for the reference line. */ -#define CHECK_b1 do { \ - if (pa != thisrun) while (b1 <= a0 && b1 < lastx) { \ - if( pb + 1 >= sp->refruns + sp->nruns) { \ - TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - b1 += pb[0] + pb[1]; \ - pb += 2; \ - } \ -} while (0) +#define CHECK_b1 \ + do \ + { \ + if (pa != thisrun) \ + while (b1 <= a0 && b1 < lastx) \ + { \ + if (pb + 1 >= sp->refruns + sp->nruns) \ + { \ + TIFFErrorExtR( \ + tif, module, "Buffer overflow at line %u of %s %u", \ + sp->line, isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ + return (-1); \ + } \ + b1 += pb[0] + pb[1]; \ + pb += 2; \ + } \ + } while (0) /* * Expand a row of 2D-encoded data. */ -#define EXPAND2D(eoflab) do { \ - while (a0 < lastx) { \ - if (pa >= thisrun + sp->nruns) { \ - TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - LOOKUP8(7, TIFFFaxMainTable, eof2d); \ - switch (TabEnt->State) { \ - case S_Pass: \ - CHECK_b1; \ - if( pb + 1 >= sp->refruns + sp->nruns) { \ - TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - b1 += *pb++; \ - RunLength += b1 - a0; \ - a0 = b1; \ - b1 += *pb++; \ - break; \ - case S_Horiz: \ - if ((pa-thisrun)&1) { \ - for (;;) { /* black first */ \ - LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ - switch (TabEnt->State) { \ - case S_TermB: \ - SETVALUE(TabEnt->Param); \ - goto doneWhite2da; \ - case S_MakeUpB: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badBlack2d; \ - } \ - } \ - doneWhite2da:; \ - for (;;) { /* then white */ \ - LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ - switch (TabEnt->State) { \ - case S_TermW: \ - SETVALUE(TabEnt->Param); \ - goto doneBlack2da; \ - case S_MakeUpW: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badWhite2d; \ - } \ - } \ - doneBlack2da:; \ - } else { \ - for (;;) { /* white first */ \ - LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ - switch (TabEnt->State) { \ - case S_TermW: \ - SETVALUE(TabEnt->Param); \ - goto doneWhite2db; \ - case S_MakeUpW: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badWhite2d; \ - } \ - } \ - doneWhite2db:; \ - for (;;) { /* then black */ \ - LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ - switch (TabEnt->State) { \ - case S_TermB: \ - SETVALUE(TabEnt->Param); \ - goto doneBlack2db; \ - case S_MakeUpB: \ - case S_MakeUp: \ - a0 += TabEnt->Param; \ - RunLength += TabEnt->Param; \ - break; \ - default: \ - goto badBlack2d; \ - } \ - } \ - doneBlack2db:; \ - } \ - CHECK_b1; \ - break; \ - case S_V0: \ - CHECK_b1; \ - SETVALUE(b1 - a0); \ - if( pb >= sp->refruns + sp->nruns) { \ - TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - b1 += *pb++; \ - break; \ - case S_VR: \ - CHECK_b1; \ - SETVALUE(b1 - a0 + TabEnt->Param); \ - if( pb >= sp->refruns + sp->nruns) { \ - TIFFErrorExtR(tif, module, "Buffer overflow at line %u of %s %u", \ - sp->line, isTiled(tif) ? "tile" : "strip", isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ - return (-1); \ - } \ - b1 += *pb++; \ - break; \ - case S_VL: \ - CHECK_b1; \ - if (b1 < (int) (a0 + TabEnt->Param)) { \ - unexpected("VL", a0); \ - goto eol2d; \ - } \ - SETVALUE(b1 - a0 - TabEnt->Param); \ - b1 -= *--pb; \ - break; \ - case S_Ext: \ - *pa++ = lastx - a0; \ - extension(a0); \ - goto eol2d; \ - case S_EOL: \ - *pa++ = lastx - a0; \ - NeedBits8(4,eof2d); \ - if (GetBits(4)) \ - unexpected("EOL", a0); \ - ClrBits(4); \ - EOLcnt = 1; \ - goto eol2d; \ - default: \ - badMain2d: \ - unexpected("MainTable", a0); \ - goto eol2d; \ - badBlack2d: \ - unexpected("BlackTable", a0); \ - goto eol2d; \ - badWhite2d: \ - unexpected("WhiteTable", a0); \ - goto eol2d; \ - eof2d: \ - prematureEOF(a0); \ - CLEANUP_RUNS(); \ - goto eoflab; \ - } \ - } \ - if (RunLength) { \ - if (RunLength + a0 < lastx) { \ - /* expect a final V0 */ \ - NeedBits8(1,eof2d); \ - if (!GetBits(1)) \ - goto badMain2d; \ - ClrBits(1); \ - } \ - SETVALUE(0); \ - } \ -eol2d: \ - CLEANUP_RUNS(); \ -} while (0) +#define EXPAND2D(eoflab) \ + do \ + { \ + while (a0 < lastx) \ + { \ + if (pa >= thisrun + sp->nruns) \ + { \ + TIFFErrorExtR( \ + tif, module, "Buffer overflow at line %u of %s %u", \ + sp->line, isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip); \ + return (-1); \ + } \ + LOOKUP8(7, TIFFFaxMainTable, eof2d); \ + switch (TabEnt->State) \ + { \ + case S_Pass: \ + CHECK_b1; \ + if (pb + 1 >= sp->refruns + sp->nruns) \ + { \ + TIFFErrorExtR(tif, module, \ + "Buffer overflow at line %u of %s %u", \ + sp->line, \ + isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile \ + : tif->tif_curstrip); \ + return (-1); \ + } \ + b1 += *pb++; \ + RunLength += b1 - a0; \ + a0 = b1; \ + b1 += *pb++; \ + break; \ + case S_Horiz: \ + if ((pa - thisrun) & 1) \ + { \ + for (;;) \ + { /* black first */ \ + LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ + switch (TabEnt->State) \ + { \ + case S_TermB: \ + SETVALUE(TabEnt->Param); \ + goto doneWhite2da; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badBlack2d; \ + } \ + } \ + doneWhite2da:; \ + for (;;) \ + { /* then white */ \ + LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ + switch (TabEnt->State) \ + { \ + case S_TermW: \ + SETVALUE(TabEnt->Param); \ + goto doneBlack2da; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badWhite2d; \ + } \ + } \ + doneBlack2da:; \ + } \ + else \ + { \ + for (;;) \ + { /* white first */ \ + LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \ + switch (TabEnt->State) \ + { \ + case S_TermW: \ + SETVALUE(TabEnt->Param); \ + goto doneWhite2db; \ + case S_MakeUpW: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badWhite2d; \ + } \ + } \ + doneWhite2db:; \ + for (;;) \ + { /* then black */ \ + LOOKUP16(13, TIFFFaxBlackTable, eof2d); \ + switch (TabEnt->State) \ + { \ + case S_TermB: \ + SETVALUE(TabEnt->Param); \ + goto doneBlack2db; \ + case S_MakeUpB: \ + case S_MakeUp: \ + a0 += TabEnt->Param; \ + RunLength += TabEnt->Param; \ + break; \ + default: \ + goto badBlack2d; \ + } \ + } \ + doneBlack2db:; \ + } \ + CHECK_b1; \ + break; \ + case S_V0: \ + CHECK_b1; \ + SETVALUE(b1 - a0); \ + if (pb >= sp->refruns + sp->nruns) \ + { \ + TIFFErrorExtR(tif, module, \ + "Buffer overflow at line %u of %s %u", \ + sp->line, \ + isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile \ + : tif->tif_curstrip); \ + return (-1); \ + } \ + b1 += *pb++; \ + break; \ + case S_VR: \ + CHECK_b1; \ + SETVALUE(b1 - a0 + TabEnt->Param); \ + if (pb >= sp->refruns + sp->nruns) \ + { \ + TIFFErrorExtR(tif, module, \ + "Buffer overflow at line %u of %s %u", \ + sp->line, \ + isTiled(tif) ? "tile" : "strip", \ + isTiled(tif) ? tif->tif_curtile \ + : tif->tif_curstrip); \ + return (-1); \ + } \ + b1 += *pb++; \ + break; \ + case S_VL: \ + CHECK_b1; \ + if (b1 < (int)(a0 + TabEnt->Param)) \ + { \ + unexpected("VL", a0); \ + goto eol2d; \ + } \ + SETVALUE(b1 - a0 - TabEnt->Param); \ + b1 -= *--pb; \ + break; \ + case S_Ext: \ + *pa++ = lastx - a0; \ + extension(a0); \ + goto eol2d; \ + case S_EOL: \ + *pa++ = lastx - a0; \ + NeedBits8(4, eof2d); \ + if (GetBits(4)) \ + unexpected("EOL", a0); \ + ClrBits(4); \ + EOLcnt = 1; \ + goto eol2d; \ + default: \ + badMain2d: \ + unexpected("MainTable", a0); \ + goto eol2d; \ + badBlack2d: \ + unexpected("BlackTable", a0); \ + goto eol2d; \ + badWhite2d: \ + unexpected("WhiteTable", a0); \ + goto eol2d; \ + eof2d: \ + prematureEOF(a0); \ + CLEANUP_RUNS(); \ + goto eoflab; \ + } \ + } \ + if (RunLength) \ + { \ + if (RunLength + a0 < lastx) \ + { \ + /* expect a final V0 */ \ + NeedBits8(1, eof2d); \ + if (!GetBits(1)) \ + goto badMain2d; \ + ClrBits(1); \ + } \ + SETVALUE(0); \ + } \ + eol2d: \ + CLEANUP_RUNS(); \ + } while (0) #endif /* _FAX3_ */ diff --git a/libtiff/tif_flush.c b/libtiff/tif_flush.c index ebd2ef33..ff9c1e24 100644 --- a/libtiff/tif_flush.c +++ b/libtiff/tif_flush.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -27,30 +27,28 @@ */ #include "tiffiop.h" -int -TIFFFlush(TIFF* tif) +int TIFFFlush(TIFF *tif) { - if( tif->tif_mode == O_RDONLY ) + if (tif->tif_mode == O_RDONLY) return 1; if (!TIFFFlushData(tif)) return (0); - - /* In update (r+) mode we try to detect the case where - only the strip/tile map has been altered, and we try to - rewrite only that portion of the directory without + + /* In update (r+) mode we try to detect the case where + only the strip/tile map has been altered, and we try to + rewrite only that portion of the directory without making any other changes */ - - if( (tif->tif_flags & TIFF_DIRTYSTRIP) - && !(tif->tif_flags & TIFF_DIRTYDIRECT) - && tif->tif_mode == O_RDWR ) + + if ((tif->tif_flags & TIFF_DIRTYSTRIP) && + !(tif->tif_flags & TIFF_DIRTYDIRECT) && tif->tif_mode == O_RDWR) { - if( TIFFForceStrileArrayWriting(tif) ) + if (TIFFForceStrileArrayWriting(tif)) return 1; } - if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP)) - && !TIFFRewriteDirectory(tif)) + if ((tif->tif_flags & (TIFF_DIRTYDIRECT | TIFF_DIRTYSTRIP)) && + !TIFFRewriteDirectory(tif)) return (0); return (1); @@ -75,45 +73,43 @@ TIFFFlush(TIFF* tif) * * Returns 1 in case of success, 0 otherwise. */ -int TIFFForceStrileArrayWriting(TIFF* tif) +int TIFFForceStrileArrayWriting(TIFF *tif) { static const char module[] = "TIFFForceStrileArrayWriting"; const int isTiled = TIFFIsTiled(tif); if (tif->tif_mode == O_RDONLY) { - TIFFErrorExtR(tif, tif->tif_name, - "File opened in read-only mode"); + TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode"); return 0; } - if( tif->tif_diroff == 0 ) + if (tif->tif_diroff == 0) { - TIFFErrorExtR(tif, module, - "Directory has not yet been written"); + TIFFErrorExtR(tif, module, "Directory has not yet been written"); return 0; } - if( (tif->tif_flags & TIFF_DIRTYDIRECT) != 0 ) + if ((tif->tif_flags & TIFF_DIRTYDIRECT) != 0) { TIFFErrorExtR(tif, module, - "Directory has changes other than the strile arrays. " - "TIFFRewriteDirectory() should be called instead"); + "Directory has changes other than the strile arrays. " + "TIFFRewriteDirectory() should be called instead"); return 0; } - if( !(tif->tif_flags & TIFF_DIRTYSTRIP) ) + if (!(tif->tif_flags & TIFF_DIRTYSTRIP)) { - if( !(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && - tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0) ) + if (!(tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && + tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)) { TIFFErrorExtR(tif, module, - "Function not called together with " - "TIFFDeferStrileArrayWriting()"); + "Function not called together with " + "TIFFDeferStrileArrayWriting()"); return 0; } @@ -121,18 +117,14 @@ int TIFFForceStrileArrayWriting(TIFF* tif) return 0; } - if( _TIFFRewriteField( tif, - isTiled ? TIFFTAG_TILEOFFSETS : - TIFFTAG_STRIPOFFSETS, - TIFF_LONG8, - tif->tif_dir.td_nstrips, - tif->tif_dir.td_stripoffset_p ) - && _TIFFRewriteField( tif, - isTiled ? TIFFTAG_TILEBYTECOUNTS : - TIFFTAG_STRIPBYTECOUNTS, - TIFF_LONG8, - tif->tif_dir.td_nstrips, - tif->tif_dir.td_stripbytecount_p ) ) + if (_TIFFRewriteField(tif, + isTiled ? TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS, + TIFF_LONG8, tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripoffset_p) && + _TIFFRewriteField( + tif, isTiled ? TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS, + TIFF_LONG8, tif->tif_dir.td_nstrips, + tif->tif_dir.td_stripbytecount_p)) { tif->tif_flags &= ~TIFF_DIRTYSTRIP; tif->tif_flags &= ~TIFF_BEENWRITING; @@ -149,17 +141,17 @@ int TIFFForceStrileArrayWriting(TIFF* tif) * is not set, so that TIFFFlush() will proceed to write out the directory. * The documentation says returning 1 is an error indicator, but not having * been writing isn't exactly a an error. Hopefully this doesn't cause - * problems for other people. + * problems for other people. */ -int -TIFFFlushData(TIFF* tif) +int TIFFFlushData(TIFF *tif) { - if ((tif->tif_flags & TIFF_BEENWRITING) == 0) - return (1); - if (tif->tif_flags & TIFF_POSTENCODE) { - tif->tif_flags &= ~TIFF_POSTENCODE; - if (!(*tif->tif_postencode)(tif)) - return (0); - } - return (TIFFFlushData1(tif)); + if ((tif->tif_flags & TIFF_BEENWRITING) == 0) + return (1); + if (tif->tif_flags & TIFF_POSTENCODE) + { + tif->tif_flags &= ~TIFF_POSTENCODE; + if (!(*tif->tif_postencode)(tif)) + return (0); + } + return (TIFFFlushData1(tif)); } diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c index 6b481a6b..41f7dfd7 100644 --- a/libtiff/tif_getimage.c +++ b/libtiff/tif_getimage.c @@ -2,23 +2,23 @@ * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -28,22 +28,22 @@ * Read and return a packed RGBA image. */ #include "tiffiop.h" -#include <stdio.h> #include <limits.h> +#include <stdio.h> -static int gtTileContig(TIFFRGBAImage*, uint32_t*, uint32_t, uint32_t); -static int gtTileSeparate(TIFFRGBAImage*, uint32_t*, uint32_t, uint32_t); -static int gtStripContig(TIFFRGBAImage*, uint32_t*, uint32_t, uint32_t); -static int gtStripSeparate(TIFFRGBAImage*, uint32_t*, uint32_t, uint32_t); -static int PickContigCase(TIFFRGBAImage*); -static int PickSeparateCase(TIFFRGBAImage*); +static int gtTileContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); +static int gtTileSeparate(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); +static int gtStripContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); +static int gtStripSeparate(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); +static int PickContigCase(TIFFRGBAImage *); +static int PickSeparateCase(TIFFRGBAImage *); -static int BuildMapUaToAa(TIFFRGBAImage* img); -static int BuildMapBitdepth16To8(TIFFRGBAImage* img); +static int BuildMapUaToAa(TIFFRGBAImage *img); +static int BuildMapBitdepth16To8(TIFFRGBAImage *img); static const char photoTag[] = "PhotometricInterpretation"; -/* +/* * Helper constants used in Orientation tag handling */ #define FLIP_VERTICALLY 0x01 @@ -56,15 +56,22 @@ static const char photoTag[] = "PhotometricInterpretation"; */ static const TIFFDisplay display_sRGB = { - { /* XYZ -> luminance matrix */ - { 3.2410F, -1.5374F, -0.4986F }, - { -0.9692F, 1.8760F, 0.0416F }, - { 0.0556F, -0.2040F, 1.0570F } - }, - 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */ - 255, 255, 255, /* Pixel values for ref. white */ - 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */ - 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */ + {/* XYZ -> luminance matrix */ + {3.2410F, -1.5374F, -0.4986F}, + {-0.9692F, 1.8760F, 0.0416F}, + {0.0556F, -0.2040F, 1.0570F}}, + 100.0F, + 100.0F, + 100.0F, /* Light o/p for reference white */ + 255, + 255, + 255, /* Pixel values for ref. white */ + 1.0F, + 1.0F, + 1.0F, /* Residual light o/p for black pixel */ + 2.4F, + 2.4F, + 2.4F, /* Gamma values for the three guns */ }; /* @@ -73,443 +80,525 @@ static const TIFFDisplay display_sRGB = { * be handled. If 0 is returned, emsg contains the reason * why it is being rejected. */ -int -TIFFRGBAImageOK(TIFF* tif, char emsg[EMSG_BUF_SIZE]) -{ - TIFFDirectory* td = &tif->tif_dir; - uint16_t photometric; - int colorchannels; - - if (!tif->tif_decodestatus) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, requested compression method is not configured"); - return (0); - } - switch (td->td_bitspersample) { - case 1: - case 2: - case 4: - case 8: - case 16: - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle images with %"PRIu16"-bit samples", - td->td_bitspersample); - return (0); - } - if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle images with IEEE floating-point samples"); +int TIFFRGBAImageOK(TIFF *tif, char emsg[EMSG_BUF_SIZE]) +{ + TIFFDirectory *td = &tif->tif_dir; + uint16_t photometric; + int colorchannels; + + if (!tif->tif_decodestatus) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, requested compression method is not configured"); + return (0); + } + switch (td->td_bitspersample) + { + case 1: + case 2: + case 4: + case 8: + case 16: + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle images with %" PRIu16 + "-bit samples", + td->td_bitspersample); + return (0); + } + if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle images with IEEE floating-point samples"); + return (0); + } + colorchannels = td->td_samplesperpixel - td->td_extrasamples; + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) + { + switch (colorchannels) + { + case 1: + photometric = PHOTOMETRIC_MINISBLACK; + break; + case 3: + photometric = PHOTOMETRIC_RGB; + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag", + photoTag); + return (0); + } + } + switch (photometric) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + td->td_samplesperpixel != 1 && td->td_bitspersample < 8) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle contiguous data with %s=%" PRIu16 + ", " + "and %s=%" PRIu16 " and Bits/Sample=%" PRIu16 "", + photoTag, photometric, "Samples/pixel", + td->td_samplesperpixel, td->td_bitspersample); + return (0); + } + /* + * We should likely validate that any extra samples are either + * to be ignored, or are alpha, and if alpha we should try to use + * them. But for now we won't bother with this. + */ + break; + case PHOTOMETRIC_YCBCR: + /* + * TODO: if at all meaningful and useful, make more complete + * support check here, or better still, refactor to let supporting + * code decide whether there is support and what meaningful + * error to return + */ + break; + case PHOTOMETRIC_RGB: + if (colorchannels < 3) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle RGB image with %s=%d", + "Color channels", colorchannels); return (0); + } + break; + case PHOTOMETRIC_SEPARATED: + { + uint16_t inkset; + TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); + if (inkset != INKSET_CMYK) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle separated image with %s=%d", + "InkSet", inkset); + return 0; + } + if (td->td_samplesperpixel < 4) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle separated image with %s=%" PRIu16, + "Samples/pixel", td->td_samplesperpixel); + return 0; + } + break; } - colorchannels = td->td_samplesperpixel - td->td_extrasamples; - if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) { - switch (colorchannels) { - case 1: - photometric = PHOTOMETRIC_MINISBLACK; - break; - case 3: - photometric = PHOTOMETRIC_RGB; - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag", photoTag); - return (0); - } - } - switch (photometric) { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_PALETTE: - if (td->td_planarconfig == PLANARCONFIG_CONTIG - && td->td_samplesperpixel != 1 - && td->td_bitspersample < 8 ) { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle contiguous data with %s=%"PRIu16", " - "and %s=%"PRIu16" and Bits/Sample=%"PRIu16"", - photoTag, photometric, - "Samples/pixel", td->td_samplesperpixel, - td->td_bitspersample); - return (0); - } - /* - * We should likely validate that any extra samples are either - * to be ignored, or are alpha, and if alpha we should try to use - * them. But for now we won't bother with this. - */ - break; - case PHOTOMETRIC_YCBCR: - /* - * TODO: if at all meaningful and useful, make more complete - * support check here, or better still, refactor to let supporting - * code decide whether there is support and what meaningful - * error to return - */ - break; - case PHOTOMETRIC_RGB: - if (colorchannels < 3) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle RGB image with %s=%d", - "Color channels", colorchannels); - return (0); - } - break; - case PHOTOMETRIC_SEPARATED: - { - uint16_t inkset; - TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); - if (inkset != INKSET_CMYK) { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle separated image with %s=%d", - "InkSet", inkset); - return 0; - } - if (td->td_samplesperpixel < 4) { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle separated image with %s=%"PRIu16, - "Samples/pixel", td->td_samplesperpixel); - return 0; - } - break; - } - case PHOTOMETRIC_LOGL: - if (td->td_compression != COMPRESSION_SGILOG) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, LogL data must have %s=%d", - "Compression", COMPRESSION_SGILOG); - return (0); - } - break; - case PHOTOMETRIC_LOGLUV: - if (td->td_compression != COMPRESSION_SGILOG && - td->td_compression != COMPRESSION_SGILOG24) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, LogLuv data must have %s=%d or %d", - "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); - return (0); - } - if (td->td_planarconfig != PLANARCONFIG_CONTIG) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle LogLuv images with %s=%"PRIu16, - "Planarconfiguration", td->td_planarconfig); - return (0); - } - if ( td->td_samplesperpixel != 3 || colorchannels != 3 ) { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle image with %s=%"PRIu16", %s=%d", - "Samples/pixel", td->td_samplesperpixel, - "colorchannels", colorchannels); - return 0; - } - break; - case PHOTOMETRIC_CIELAB: - if ( td->td_samplesperpixel != 3 || colorchannels != 3 || (td->td_bitspersample != 8 && td->td_bitspersample != 16) ) { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle image with %s=%"PRIu16", %s=%d and %s=%"PRIu16, - "Samples/pixel", td->td_samplesperpixel, - "colorchannels", colorchannels, - "Bits/sample", td->td_bitspersample); - return 0; - } - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image with %s=%"PRIu16, - photoTag, photometric); - return (0); - } - return (1); -} - -void -TIFFRGBAImageEnd(TIFFRGBAImage* img) -{ - if (img->Map) { - _TIFFfreeExt(img->tif, img->Map); - img->Map = NULL; - } - if (img->BWmap) { - _TIFFfreeExt(img->tif, img->BWmap); - img->BWmap = NULL; - } - if (img->PALmap) { - _TIFFfreeExt(img->tif, img->PALmap); - img->PALmap = NULL; - } - if (img->ycbcr) { - _TIFFfreeExt(img->tif, img->ycbcr); - img->ycbcr = NULL; - } - if (img->cielab) { - _TIFFfreeExt(img->tif, img->cielab); - img->cielab = NULL; - } - if (img->UaToAa) { - _TIFFfreeExt(img->tif, img->UaToAa); - img->UaToAa = NULL; - } - if (img->Bitdepth16To8) { - _TIFFfreeExt(img->tif, img->Bitdepth16To8); - img->Bitdepth16To8 = NULL; - } - - if( img->redcmap ) { - _TIFFfreeExt(img->tif, img->redcmap); - _TIFFfreeExt(img->tif, img->greencmap); - _TIFFfreeExt(img->tif, img->bluecmap); - img->redcmap = img->greencmap = img->bluecmap = NULL; - } -} - -static int -isCCITTCompression(TIFF* tif) + case PHOTOMETRIC_LOGL: + if (td->td_compression != COMPRESSION_SGILOG) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, LogL data must have %s=%d", "Compression", + COMPRESSION_SGILOG); + return (0); + } + break; + case PHOTOMETRIC_LOGLUV: + if (td->td_compression != COMPRESSION_SGILOG && + td->td_compression != COMPRESSION_SGILOG24) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, LogLuv data must have %s=%d or %d", + "Compression", COMPRESSION_SGILOG, + COMPRESSION_SGILOG24); + return (0); + } + if (td->td_planarconfig != PLANARCONFIG_CONTIG) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle LogLuv images with %s=%" PRIu16, + "Planarconfiguration", td->td_planarconfig); + return (0); + } + if (td->td_samplesperpixel != 3 || colorchannels != 3) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle image with %s=%" PRIu16 + ", %s=%d", + "Samples/pixel", td->td_samplesperpixel, + "colorchannels", colorchannels); + return 0; + } + break; + case PHOTOMETRIC_CIELAB: + if (td->td_samplesperpixel != 3 || colorchannels != 3 || + (td->td_bitspersample != 8 && td->td_bitspersample != 16)) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle image with %s=%" PRIu16 + ", %s=%d and %s=%" PRIu16, + "Samples/pixel", td->td_samplesperpixel, + "colorchannels", colorchannels, "Bits/sample", + td->td_bitspersample); + return 0; + } + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle image with %s=%" PRIu16, photoTag, + photometric); + return (0); + } + return (1); +} + +void TIFFRGBAImageEnd(TIFFRGBAImage *img) +{ + if (img->Map) + { + _TIFFfreeExt(img->tif, img->Map); + img->Map = NULL; + } + if (img->BWmap) + { + _TIFFfreeExt(img->tif, img->BWmap); + img->BWmap = NULL; + } + if (img->PALmap) + { + _TIFFfreeExt(img->tif, img->PALmap); + img->PALmap = NULL; + } + if (img->ycbcr) + { + _TIFFfreeExt(img->tif, img->ycbcr); + img->ycbcr = NULL; + } + if (img->cielab) + { + _TIFFfreeExt(img->tif, img->cielab); + img->cielab = NULL; + } + if (img->UaToAa) + { + _TIFFfreeExt(img->tif, img->UaToAa); + img->UaToAa = NULL; + } + if (img->Bitdepth16To8) + { + _TIFFfreeExt(img->tif, img->Bitdepth16To8); + img->Bitdepth16To8 = NULL; + } + + if (img->redcmap) + { + _TIFFfreeExt(img->tif, img->redcmap); + _TIFFfreeExt(img->tif, img->greencmap); + _TIFFfreeExt(img->tif, img->bluecmap); + img->redcmap = img->greencmap = img->bluecmap = NULL; + } +} + +static int isCCITTCompression(TIFF *tif) { uint16_t compress; TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress); return (compress == COMPRESSION_CCITTFAX3 || - compress == COMPRESSION_CCITTFAX4 || - compress == COMPRESSION_CCITTRLE || - compress == COMPRESSION_CCITTRLEW); -} - -int -TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[EMSG_BUF_SIZE]) -{ - uint16_t* sampleinfo; - uint16_t extrasamples; - uint16_t planarconfig; - uint16_t compress; - int colorchannels; - uint16_t *red_orig, *green_orig, *blue_orig; - int n_color; - - if( !TIFFRGBAImageOK(tif, emsg) ) - return 0; - - /* Initialize to normal values */ - img->row_offset = 0; - img->col_offset = 0; - img->redcmap = NULL; - img->greencmap = NULL; - img->bluecmap = NULL; - img->Map = NULL; - img->BWmap = NULL; - img->PALmap = NULL; - img->ycbcr = NULL; - img->cielab = NULL; - img->UaToAa = NULL; - img->Bitdepth16To8 = NULL; - img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */ - - img->tif = tif; - img->stoponerr = stop; - TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample); - switch (img->bitspersample) { - case 1: - case 2: - case 4: - case 8: - case 16: - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle images with %"PRIu16"-bit samples", - img->bitspersample); - goto fail_return; - } - img->alpha = 0; - TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); - TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, - &extrasamples, &sampleinfo); - if (extrasamples >= 1) - { - switch (sampleinfo[0]) { - case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */ - if (img->samplesperpixel > 3) /* correct info about alpha channel */ - img->alpha = EXTRASAMPLE_ASSOCALPHA; - break; - case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */ - case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ - img->alpha = sampleinfo[0]; - break; - } - } + compress == COMPRESSION_CCITTFAX4 || + compress == COMPRESSION_CCITTRLE || + compress == COMPRESSION_CCITTRLEW); +} + +int TIFFRGBAImageBegin(TIFFRGBAImage *img, TIFF *tif, int stop, + char emsg[EMSG_BUF_SIZE]) +{ + uint16_t *sampleinfo; + uint16_t extrasamples; + uint16_t planarconfig; + uint16_t compress; + int colorchannels; + uint16_t *red_orig, *green_orig, *blue_orig; + int n_color; + + if (!TIFFRGBAImageOK(tif, emsg)) + return 0; + + /* Initialize to normal values */ + img->row_offset = 0; + img->col_offset = 0; + img->redcmap = NULL; + img->greencmap = NULL; + img->bluecmap = NULL; + img->Map = NULL; + img->BWmap = NULL; + img->PALmap = NULL; + img->ycbcr = NULL; + img->cielab = NULL; + img->UaToAa = NULL; + img->Bitdepth16To8 = NULL; + img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */ + + img->tif = tif; + img->stoponerr = stop; + TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample); + switch (img->bitspersample) + { + case 1: + case 2: + case 4: + case 8: + case 16: + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle images with %" PRIu16 + "-bit samples", + img->bitspersample); + goto fail_return; + } + img->alpha = 0; + TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel); + TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, + &sampleinfo); + if (extrasamples >= 1) + { + switch (sampleinfo[0]) + { + case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without + */ + if (img->samplesperpixel > + 3) /* correct info about alpha channel */ + img->alpha = EXTRASAMPLE_ASSOCALPHA; + break; + case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */ + case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */ + img->alpha = sampleinfo[0]; + break; + } + } #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA - if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) - img->photometric = PHOTOMETRIC_MINISWHITE; - - if( extrasamples == 0 - && img->samplesperpixel == 4 - && img->photometric == PHOTOMETRIC_RGB ) - { - img->alpha = EXTRASAMPLE_ASSOCALPHA; - extrasamples = 1; - } + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) + img->photometric = PHOTOMETRIC_MINISWHITE; + + if (extrasamples == 0 && img->samplesperpixel == 4 && + img->photometric == PHOTOMETRIC_RGB) + { + img->alpha = EXTRASAMPLE_ASSOCALPHA; + extrasamples = 1; + } #endif - colorchannels = img->samplesperpixel - extrasamples; - TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress); - TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); - if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) { - switch (colorchannels) { - case 1: - if (isCCITTCompression(tif)) - img->photometric = PHOTOMETRIC_MINISWHITE; - else - img->photometric = PHOTOMETRIC_MINISBLACK; - break; - case 3: - img->photometric = PHOTOMETRIC_RGB; - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag", photoTag); - goto fail_return; - } - } - switch (img->photometric) { - case PHOTOMETRIC_PALETTE: - if (!TIFFGetField(tif, TIFFTAG_COLORMAP, - &red_orig, &green_orig, &blue_orig)) { - snprintf(emsg, EMSG_BUF_SIZE, "Missing required \"Colormap\" tag"); - goto fail_return; - } - - /* copy the colormaps so we can modify them */ - n_color = (1U << img->bitspersample); - img->redcmap = (uint16_t *) _TIFFmallocExt(tif, sizeof(uint16_t) * n_color); - img->greencmap = (uint16_t *) _TIFFmallocExt(tif, sizeof(uint16_t) * n_color); - img->bluecmap = (uint16_t *) _TIFFmallocExt(tif, sizeof(uint16_t) * n_color); - if( !img->redcmap || !img->greencmap || !img->bluecmap ) { - snprintf(emsg, EMSG_BUF_SIZE, "Out of memory for colormap copy"); - goto fail_return; - } - - _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 ); - _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 ); - _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 ); - - /* fall through... */ - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - if (planarconfig == PLANARCONFIG_CONTIG - && img->samplesperpixel != 1 - && img->bitspersample < 8 ) { - snprintf(emsg, EMSG_BUF_SIZE, - "Sorry, can not handle contiguous data with %s=%"PRIu16", " - "and %s=%"PRIu16" and Bits/Sample=%"PRIu16, - photoTag, img->photometric, - "Samples/pixel", img->samplesperpixel, - img->bitspersample); - goto fail_return; - } - break; - case PHOTOMETRIC_YCBCR: - /* It would probably be nice to have a reality check here. */ - if (planarconfig == PLANARCONFIG_CONTIG) - /* can rely on libjpeg to convert to RGB */ - /* XXX should restore current state on exit */ - switch (compress) { - case COMPRESSION_JPEG: - /* - * TODO: when complete tests verify complete desubsampling - * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in - * favor of tif_getimage.c native handling - */ - TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); - img->photometric = PHOTOMETRIC_RGB; - break; - default: - /* do nothing */; - break; - } - /* - * TODO: if at all meaningful and useful, make more complete - * support check here, or better still, refactor to let supporting - * code decide whether there is support and what meaningful - * error to return - */ - break; - case PHOTOMETRIC_RGB: - if (colorchannels < 3) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle RGB image with %s=%d", - "Color channels", colorchannels); - goto fail_return; - } - break; - case PHOTOMETRIC_SEPARATED: - { - uint16_t inkset; - TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); - if (inkset != INKSET_CMYK) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle separated image with %s=%"PRIu16, - "InkSet", inkset); - goto fail_return; - } - if (img->samplesperpixel < 4) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle separated image with %s=%"PRIu16, - "Samples/pixel", img->samplesperpixel); - goto fail_return; - } - } - break; - case PHOTOMETRIC_LOGL: - if (compress != COMPRESSION_SGILOG) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, LogL data must have %s=%d", - "Compression", COMPRESSION_SGILOG); - goto fail_return; - } - TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); - img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */ - img->bitspersample = 8; - break; - case PHOTOMETRIC_LOGLUV: - if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, LogLuv data must have %s=%d or %d", - "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24); - goto fail_return; - } - if (planarconfig != PLANARCONFIG_CONTIG) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle LogLuv images with %s=%"PRIu16, - "Planarconfiguration", planarconfig); - return (0); - } - TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); - img->photometric = PHOTOMETRIC_RGB; /* little white lie */ - img->bitspersample = 8; - break; - case PHOTOMETRIC_CIELAB: - break; - default: - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image with %s=%"PRIu16, - photoTag, img->photometric); - goto fail_return; - } - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); - TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); - img->isContig = - !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1); - if (img->isContig) { - if (!PickContigCase(img)) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image"); - goto fail_return; - } - } else { - if (!PickSeparateCase(img)) { - snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image"); - goto fail_return; - } - } - return 1; - - fail_return: - TIFFRGBAImageEnd( img ); - return 0; + colorchannels = img->samplesperpixel - extrasamples; + TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress); + TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig); + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) + { + switch (colorchannels) + { + case 1: + if (isCCITTCompression(tif)) + img->photometric = PHOTOMETRIC_MINISWHITE; + else + img->photometric = PHOTOMETRIC_MINISBLACK; + break; + case 3: + img->photometric = PHOTOMETRIC_RGB; + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, "Missing needed %s tag", + photoTag); + goto fail_return; + } + } + switch (img->photometric) + { + case PHOTOMETRIC_PALETTE: + if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &red_orig, &green_orig, + &blue_orig)) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Missing required \"Colormap\" tag"); + goto fail_return; + } + + /* copy the colormaps so we can modify them */ + n_color = (1U << img->bitspersample); + img->redcmap = + (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color); + img->greencmap = + (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color); + img->bluecmap = + (uint16_t *)_TIFFmallocExt(tif, sizeof(uint16_t) * n_color); + if (!img->redcmap || !img->greencmap || !img->bluecmap) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Out of memory for colormap copy"); + goto fail_return; + } + + _TIFFmemcpy(img->redcmap, red_orig, n_color * 2); + _TIFFmemcpy(img->greencmap, green_orig, n_color * 2); + _TIFFmemcpy(img->bluecmap, blue_orig, n_color * 2); + + /* fall through... */ + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + if (planarconfig == PLANARCONFIG_CONTIG && + img->samplesperpixel != 1 && img->bitspersample < 8) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle contiguous data with %s=%" PRIu16 + ", " + "and %s=%" PRIu16 " and Bits/Sample=%" PRIu16, + photoTag, img->photometric, "Samples/pixel", + img->samplesperpixel, img->bitspersample); + goto fail_return; + } + break; + case PHOTOMETRIC_YCBCR: + /* It would probably be nice to have a reality check here. */ + if (planarconfig == PLANARCONFIG_CONTIG) + /* can rely on libjpeg to convert to RGB */ + /* XXX should restore current state on exit */ + switch (compress) + { + case COMPRESSION_JPEG: + /* + * TODO: when complete tests verify complete + * desubsampling and YCbCr handling, remove use of + * TIFFTAG_JPEGCOLORMODE in favor of tif_getimage.c + * native handling + */ + TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, + JPEGCOLORMODE_RGB); + img->photometric = PHOTOMETRIC_RGB; + break; + default: + /* do nothing */; + break; + } + /* + * TODO: if at all meaningful and useful, make more complete + * support check here, or better still, refactor to let supporting + * code decide whether there is support and what meaningful + * error to return + */ + break; + case PHOTOMETRIC_RGB: + if (colorchannels < 3) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle RGB image with %s=%d", + "Color channels", colorchannels); + goto fail_return; + } + break; + case PHOTOMETRIC_SEPARATED: + { + uint16_t inkset; + TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset); + if (inkset != INKSET_CMYK) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle separated image with %s=%" PRIu16, + "InkSet", inkset); + goto fail_return; + } + if (img->samplesperpixel < 4) + { + snprintf( + emsg, EMSG_BUF_SIZE, + "Sorry, can not handle separated image with %s=%" PRIu16, + "Samples/pixel", img->samplesperpixel); + goto fail_return; + } + } + break; + case PHOTOMETRIC_LOGL: + if (compress != COMPRESSION_SGILOG) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, LogL data must have %s=%d", "Compression", + COMPRESSION_SGILOG); + goto fail_return; + } + TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); + img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */ + img->bitspersample = 8; + break; + case PHOTOMETRIC_LOGLUV: + if (compress != COMPRESSION_SGILOG && + compress != COMPRESSION_SGILOG24) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, LogLuv data must have %s=%d or %d", + "Compression", COMPRESSION_SGILOG, + COMPRESSION_SGILOG24); + goto fail_return; + } + if (planarconfig != PLANARCONFIG_CONTIG) + { + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle LogLuv images with %s=%" PRIu16, + "Planarconfiguration", planarconfig); + return (0); + } + TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT); + img->photometric = PHOTOMETRIC_RGB; /* little white lie */ + img->bitspersample = 8; + break; + case PHOTOMETRIC_CIELAB: + break; + default: + snprintf(emsg, EMSG_BUF_SIZE, + "Sorry, can not handle image with %s=%" PRIu16, photoTag, + img->photometric); + goto fail_return; + } + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height); + TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation); + img->isContig = + !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1); + if (img->isContig) + { + if (!PickContigCase(img)) + { + snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image"); + goto fail_return; + } + } + else + { + if (!PickSeparateCase(img)) + { + snprintf(emsg, EMSG_BUF_SIZE, "Sorry, can not handle image"); + goto fail_return; + } + } + return 1; + +fail_return: + TIFFRGBAImageEnd(img); + return 0; } -int -TIFFRGBAImageGet(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) +int TIFFRGBAImageGet(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, + uint32_t h) { - if (img->get == NULL) { - TIFFErrorExtR(img->tif, TIFFFileName(img->tif), "No \"get\" routine setup"); - return (0); - } - if (img->put.any == NULL) { - TIFFErrorExtR(img->tif, TIFFFileName(img->tif), - "No \"put\" routine setupl; probably can not handle image format"); - return (0); + if (img->get == NULL) + { + TIFFErrorExtR(img->tif, TIFFFileName(img->tif), + "No \"get\" routine setup"); + return (0); + } + if (img->put.any == NULL) + { + TIFFErrorExtR( + img->tif, TIFFFileName(img->tif), + "No \"put\" routine setupl; probably can not handle image format"); + return (0); } return (*img->get)(img, raster, w, h); } @@ -518,24 +607,25 @@ TIFFRGBAImageGet(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) * Read the specified image into an ABGR-format rastertaking in account * specified orientation. */ -int -TIFFReadRGBAImageOriented(TIFF* tif, - uint32_t rwidth, uint32_t rheight, uint32_t* raster, - int orientation, int stop) +int TIFFReadRGBAImageOriented(TIFF *tif, uint32_t rwidth, uint32_t rheight, + uint32_t *raster, int orientation, int stop) { char emsg[EMSG_BUF_SIZE] = ""; TIFFRGBAImage img; int ok; - if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) { - img.req_orientation = (uint16_t)orientation; - /* XXX verify rwidth and rheight against width and height */ - ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth, - rwidth, img.height); - TIFFRGBAImageEnd(&img); - } else { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); - ok = 0; + if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) + { + img.req_orientation = (uint16_t)orientation; + /* XXX verify rwidth and rheight against width and height */ + ok = TIFFRGBAImageGet(&img, raster + (rheight - img.height) * rwidth, + rwidth, img.height); + TIFFRGBAImageEnd(&img); + } + else + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); + ok = 0; } return (ok); } @@ -544,73 +634,72 @@ TIFFReadRGBAImageOriented(TIFF* tif, * Read the specified image into an ABGR-format raster. Use bottom left * origin for raster by default. */ -int -TIFFReadRGBAImage(TIFF* tif, - uint32_t rwidth, uint32_t rheight, uint32_t* raster, int stop) -{ - return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster, - ORIENTATION_BOTLEFT, stop); -} - -static int -setorientation(TIFFRGBAImage* img) -{ - switch (img->orientation) { - case ORIENTATION_TOPLEFT: - case ORIENTATION_LEFTTOP: - if (img->req_orientation == ORIENTATION_TOPRIGHT || - img->req_orientation == ORIENTATION_RIGHTTOP) - return FLIP_HORIZONTALLY; - else if (img->req_orientation == ORIENTATION_BOTRIGHT || - img->req_orientation == ORIENTATION_RIGHTBOT) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTLEFT || - img->req_orientation == ORIENTATION_LEFTBOT) - return FLIP_VERTICALLY; - else - return 0; - case ORIENTATION_TOPRIGHT: - case ORIENTATION_RIGHTTOP: - if (img->req_orientation == ORIENTATION_TOPLEFT || - img->req_orientation == ORIENTATION_LEFTTOP) - return FLIP_HORIZONTALLY; - else if (img->req_orientation == ORIENTATION_BOTRIGHT || - img->req_orientation == ORIENTATION_RIGHTBOT) - return FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTLEFT || - img->req_orientation == ORIENTATION_LEFTBOT) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else - return 0; - case ORIENTATION_BOTRIGHT: - case ORIENTATION_RIGHTBOT: - if (img->req_orientation == ORIENTATION_TOPLEFT || - img->req_orientation == ORIENTATION_LEFTTOP) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_TOPRIGHT || - img->req_orientation == ORIENTATION_RIGHTTOP) - return FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTLEFT || - img->req_orientation == ORIENTATION_LEFTBOT) - return FLIP_HORIZONTALLY; - else - return 0; - case ORIENTATION_BOTLEFT: - case ORIENTATION_LEFTBOT: - if (img->req_orientation == ORIENTATION_TOPLEFT || - img->req_orientation == ORIENTATION_LEFTTOP) - return FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_TOPRIGHT || - img->req_orientation == ORIENTATION_RIGHTTOP) - return FLIP_HORIZONTALLY | FLIP_VERTICALLY; - else if (img->req_orientation == ORIENTATION_BOTRIGHT || - img->req_orientation == ORIENTATION_RIGHTBOT) - return FLIP_HORIZONTALLY; - else - return 0; - default: /* NOTREACHED */ - return 0; - } +int TIFFReadRGBAImage(TIFF *tif, uint32_t rwidth, uint32_t rheight, + uint32_t *raster, int stop) +{ + return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster, + ORIENTATION_BOTLEFT, stop); +} + +static int setorientation(TIFFRGBAImage *img) +{ + switch (img->orientation) + { + case ORIENTATION_TOPLEFT: + case ORIENTATION_LEFTTOP: + if (img->req_orientation == ORIENTATION_TOPRIGHT || + img->req_orientation == ORIENTATION_RIGHTTOP) + return FLIP_HORIZONTALLY; + else if (img->req_orientation == ORIENTATION_BOTRIGHT || + img->req_orientation == ORIENTATION_RIGHTBOT) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTLEFT || + img->req_orientation == ORIENTATION_LEFTBOT) + return FLIP_VERTICALLY; + else + return 0; + case ORIENTATION_TOPRIGHT: + case ORIENTATION_RIGHTTOP: + if (img->req_orientation == ORIENTATION_TOPLEFT || + img->req_orientation == ORIENTATION_LEFTTOP) + return FLIP_HORIZONTALLY; + else if (img->req_orientation == ORIENTATION_BOTRIGHT || + img->req_orientation == ORIENTATION_RIGHTBOT) + return FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTLEFT || + img->req_orientation == ORIENTATION_LEFTBOT) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else + return 0; + case ORIENTATION_BOTRIGHT: + case ORIENTATION_RIGHTBOT: + if (img->req_orientation == ORIENTATION_TOPLEFT || + img->req_orientation == ORIENTATION_LEFTTOP) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_TOPRIGHT || + img->req_orientation == ORIENTATION_RIGHTTOP) + return FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTLEFT || + img->req_orientation == ORIENTATION_LEFTBOT) + return FLIP_HORIZONTALLY; + else + return 0; + case ORIENTATION_BOTLEFT: + case ORIENTATION_LEFTBOT: + if (img->req_orientation == ORIENTATION_TOPLEFT || + img->req_orientation == ORIENTATION_LEFTTOP) + return FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_TOPRIGHT || + img->req_orientation == ORIENTATION_RIGHTTOP) + return FLIP_HORIZONTALLY | FLIP_VERTICALLY; + else if (img->req_orientation == ORIENTATION_BOTRIGHT || + img->req_orientation == ORIENTATION_RIGHTBOT) + return FLIP_HORIZONTALLY; + else + return 0; + default: /* NOTREACHED */ + return 0; + } } /* @@ -618,16 +707,16 @@ setorientation(TIFFRGBAImage* img) * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 - */ -static int -gtTileContig(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) + */ +static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, + uint32_t h) { - TIFF* tif = img->tif; + TIFF *tif = img->tif; tileContigRoutine put = img->put.contig; uint32_t col, row, y, rowstoread; tmsize_t pos; uint32_t tw, th; - unsigned char* buf = NULL; + unsigned char *buf = NULL; int32_t fromskew, toskew; uint32_t nrow; int ret = 1, flip; @@ -638,7 +727,8 @@ gtTileContig(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) tmsize_t bufsize; bufsize = TIFFTileSize(tif); - if (bufsize == 0) { + if (bufsize == 0) + { TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "No space for tile buffer"); return (0); } @@ -647,23 +737,29 @@ gtTileContig(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); flip = setorientation(img); - if (flip & FLIP_VERTICALLY) { - if ((tw + w) > INT_MAX) { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); + if (flip & FLIP_VERTICALLY) + { + if ((tw + w) > INT_MAX) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", + "unsupported tile size (too wide)"); return (0); } y = h - 1; toskew = -(int32_t)(tw + w); } - else { - if (tw > (INT_MAX + w)) { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); + else + { + if (tw > (INT_MAX + w)) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", + "unsupported tile size (too wide)"); return (0); } y = 0; toskew = -(int32_t)(tw - w); } - + /* * Leftmost tile is clipped on left side if col_offset > 0. */ @@ -673,63 +769,69 @@ gtTileContig(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) for (row = 0; ret != 0 && row < h; row += nrow) { rowstoread = th - (row + img->row_offset) % th; - nrow = (row + rowstoread > h ? h - row : rowstoread); - fromskew = leftmost_fromskew; - this_tw = leftmost_tw; - this_toskew = leftmost_toskew; - tocol = 0; - col = img->col_offset; - while (tocol < w) + nrow = (row + rowstoread > h ? h - row : rowstoread); + fromskew = leftmost_fromskew; + this_tw = leftmost_tw; + this_toskew = leftmost_toskew; + tocol = 0; + col = img->col_offset; + while (tocol < w) { - if (_TIFFReadTileAndAllocBuffer(tif, (void**) &buf, bufsize, col, - row+img->row_offset, 0, 0)==(tmsize_t)(-1) && + if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, col, + row + img->row_offset, 0, + 0) == (tmsize_t)(-1) && (buf == NULL || img->stoponerr)) { ret = 0; break; } - pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \ - ((tmsize_t) fromskew * img->samplesperpixel); - if (tocol + this_tw > w) - { - /* - * Rightmost tile is clipped on right side. - */ - fromskew = tw - (w - tocol); - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; - } - tmsize_t roffset = (tmsize_t) y * w + tocol; - (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, this_toskew, buf + pos); - tocol += this_tw; - col += this_tw; - /* - * After the leftmost tile, tiles are no longer clipped on left side. - */ - fromskew = 0; - this_tw = tw; - this_toskew = toskew; - } - - y += ((flip & FLIP_VERTICALLY) ? -(int32_t) nrow : (int32_t) nrow); + pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) + + ((tmsize_t)fromskew * img->samplesperpixel); + if (tocol + this_tw > w) + { + /* + * Rightmost tile is clipped on right side. + */ + fromskew = tw - (w - tocol); + this_tw = tw - fromskew; + this_toskew = toskew + fromskew; + } + tmsize_t roffset = (tmsize_t)y * w + tocol; + (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, + this_toskew, buf + pos); + tocol += this_tw; + col += this_tw; + /* + * After the leftmost tile, tiles are no longer clipped on left + * side. + */ + fromskew = 0; + this_tw = tw; + this_toskew = toskew; + } + + y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); } _TIFFfreeExt(img->tif, buf); - if (flip & FLIP_HORIZONTALLY) { - uint32_t line; + if (flip & FLIP_HORIZONTALLY) + { + uint32_t line; + + for (line = 0; line < h; line++) + { + uint32_t *left = raster + (line * w); + uint32_t *right = left + w - 1; - for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); - uint32_t *right = left + w - 1; - - while ( left < right ) { - uint32_t temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } + while (left < right) + { + uint32_t temp = *left; + *left = *right; + *right = temp; + left++; + right--; + } + } } return (ret); @@ -740,189 +842,203 @@ gtTileContig(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) * SamplesPerPixel > 1 * PlanarConfiguration separated * We assume that all such images are RGB. - */ -static int -gtTileSeparate(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) -{ - TIFF* tif = img->tif; - tileSeparateRoutine put = img->put.separate; - uint32_t col, row, y, rowstoread; - tmsize_t pos; - uint32_t tw, th; - unsigned char* buf = NULL; - unsigned char* p0 = NULL; - unsigned char* p1 = NULL; - unsigned char* p2 = NULL; - unsigned char* pa = NULL; - tmsize_t tilesize; - tmsize_t bufsize; - int32_t fromskew, toskew; - int alpha = img->alpha; - uint32_t nrow; - int ret = 1, flip; - uint16_t colorchannels; - uint32_t this_tw, tocol; - int32_t this_toskew, leftmost_toskew; - int32_t leftmost_fromskew; - uint32_t leftmost_tw; - - tilesize = TIFFTileSize(tif); - bufsize = _TIFFMultiplySSize(tif, alpha?4:3,tilesize, "gtTileSeparate"); - if (bufsize == 0) { - return (0); - } - - TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); - TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); - - flip = setorientation(img); - if (flip & FLIP_VERTICALLY) { - if ((tw + w) > INT_MAX) { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); + */ +static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, + uint32_t h) +{ + TIFF *tif = img->tif; + tileSeparateRoutine put = img->put.separate; + uint32_t col, row, y, rowstoread; + tmsize_t pos; + uint32_t tw, th; + unsigned char *buf = NULL; + unsigned char *p0 = NULL; + unsigned char *p1 = NULL; + unsigned char *p2 = NULL; + unsigned char *pa = NULL; + tmsize_t tilesize; + tmsize_t bufsize; + int32_t fromskew, toskew; + int alpha = img->alpha; + uint32_t nrow; + int ret = 1, flip; + uint16_t colorchannels; + uint32_t this_tw, tocol; + int32_t this_toskew, leftmost_toskew; + int32_t leftmost_fromskew; + uint32_t leftmost_tw; + + tilesize = TIFFTileSize(tif); + bufsize = + _TIFFMultiplySSize(tif, alpha ? 4 : 3, tilesize, "gtTileSeparate"); + if (bufsize == 0) + { + return (0); + } + + TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw); + TIFFGetField(tif, TIFFTAG_TILELENGTH, &th); + + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) + { + if ((tw + w) > INT_MAX) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", + "unsupported tile size (too wide)"); return (0); } - y = h - 1; - toskew = -(int32_t)(tw + w); - } - else { - if (tw > (INT_MAX + w)) { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", "unsupported tile size (too wide)"); + y = h - 1; + toskew = -(int32_t)(tw + w); + } + else + { + if (tw > (INT_MAX + w)) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", + "unsupported tile size (too wide)"); return (0); } - y = 0; - toskew = -(int32_t)(tw - w); - } + y = 0; + toskew = -(int32_t)(tw - w); + } - switch( img->photometric ) - { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_PALETTE: + switch (img->photometric) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: colorchannels = 1; break; - default: + default: colorchannels = 3; break; + } + + /* + * Leftmost tile is clipped on left side if col_offset > 0. + */ + leftmost_fromskew = img->col_offset % tw; + leftmost_tw = tw - leftmost_fromskew; + leftmost_toskew = toskew + leftmost_fromskew; + for (row = 0; ret != 0 && row < h; row += nrow) + { + rowstoread = th - (row + img->row_offset) % th; + nrow = (row + rowstoread > h ? h - row : rowstoread); + fromskew = leftmost_fromskew; + this_tw = leftmost_tw; + this_toskew = leftmost_toskew; + tocol = 0; + col = img->col_offset; + while (tocol < w) + { + if (buf == NULL) + { + if (_TIFFReadTileAndAllocBuffer(tif, (void **)&buf, bufsize, + col, row + img->row_offset, 0, + 0) == (tmsize_t)(-1) && + (buf == NULL || img->stoponerr)) + { + ret = 0; + break; + } + p0 = buf; + if (colorchannels == 1) + { + p2 = p1 = p0; + pa = (alpha ? (p0 + 3 * tilesize) : NULL); + } + else + { + p1 = p0 + tilesize; + p2 = p1 + tilesize; + pa = (alpha ? (p2 + tilesize) : NULL); + } + } + else if (TIFFReadTile(tif, p0, col, row + img->row_offset, 0, 0) == + (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 && + TIFFReadTile(tif, p1, col, row + img->row_offset, 0, 1) == + (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 && + TIFFReadTile(tif, p2, col, row + img->row_offset, 0, 2) == + (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (alpha && + TIFFReadTile(tif, pa, col, row + img->row_offset, 0, + colorchannels) == (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + + pos = ((row + img->row_offset) % th) * TIFFTileRowSize(tif) + + ((tmsize_t)fromskew * img->samplesperpixel); + if (tocol + this_tw > w) + { + /* + * Rightmost tile is clipped on right side. + */ + fromskew = tw - (w - tocol); + this_tw = tw - fromskew; + this_toskew = toskew + fromskew; + } + tmsize_t roffset = (tmsize_t)y * w + tocol; + (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, + this_toskew, p0 + pos, p1 + pos, p2 + pos, + (alpha ? (pa + pos) : NULL)); + tocol += this_tw; + col += this_tw; + /* + * After the leftmost tile, tiles are no longer clipped on left + * side. + */ + fromskew = 0; + this_tw = tw; + this_toskew = toskew; } - /* - * Leftmost tile is clipped on left side if col_offset > 0. - */ - leftmost_fromskew = img->col_offset % tw; - leftmost_tw = tw - leftmost_fromskew; - leftmost_toskew = toskew + leftmost_fromskew; - for (row = 0; ret != 0 && row < h; row += nrow) - { - rowstoread = th - (row + img->row_offset) % th; - nrow = (row + rowstoread > h ? h - row : rowstoread); - fromskew = leftmost_fromskew; - this_tw = leftmost_tw; - this_toskew = leftmost_toskew; - tocol = 0; - col = img->col_offset; - while (tocol < w) - { - if( buf == NULL ) - { - if (_TIFFReadTileAndAllocBuffer( - tif, (void**) &buf, bufsize, col, - row+img->row_offset,0,0)==(tmsize_t)(-1) - && (buf == NULL || img->stoponerr)) - { - ret = 0; - break; - } - p0 = buf; - if( colorchannels == 1 ) - { - p2 = p1 = p0; - pa = (alpha?(p0+3*tilesize):NULL); - } - else - { - p1 = p0 + tilesize; - p2 = p1 + tilesize; - pa = (alpha?(p2+tilesize):NULL); - } - } - else if (TIFFReadTile(tif, p0, col, - row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 - && TIFFReadTile(tif, p1, col, - row+img->row_offset,0,1) == (tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 - && TIFFReadTile(tif, p2, col, - row+img->row_offset,0,2) == (tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - if (alpha - && TIFFReadTile(tif,pa,col, - row+img->row_offset,0,colorchannels) == (tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - - pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \ - ((tmsize_t) fromskew * img->samplesperpixel); - if (tocol + this_tw > w) - { - /* - * Rightmost tile is clipped on right side. - */ - fromskew = tw - (w - tocol); - this_tw = tw - fromskew; - this_toskew = toskew + fromskew; - } - tmsize_t roffset = (tmsize_t) y * w + tocol; - (*put)(img, raster + roffset, tocol, y, this_tw, nrow, fromskew, this_toskew, \ - p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL)); - tocol += this_tw; - col += this_tw; - /* - * After the leftmost tile, tiles are no longer clipped on left side. - */ - fromskew = 0; - this_tw = tw; - this_toskew = toskew; - } - - y += ((flip & FLIP_VERTICALLY) ? -(int32_t) nrow : (int32_t) nrow); - } - - if (flip & FLIP_HORIZONTALLY) { - uint32_t line; - - for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); - uint32_t *right = left + w - 1; - - while ( left < right ) { - uint32_t temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } - } - - _TIFFfreeExt(img->tif, buf); - return (ret); + y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + } + + if (flip & FLIP_HORIZONTALLY) + { + uint32_t line; + + for (line = 0; line < h; line++) + { + uint32_t *left = raster + (line * w); + uint32_t *right = left + w - 1; + + while (left < right) + { + uint32_t temp = *left; + *left = *right; + *right = temp; + left++; + right--; + } + } + } + + _TIFFfreeExt(img->tif, buf); + return (ret); } /* @@ -930,99 +1046,110 @@ gtTileSeparate(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 - */ -static int -gtStripContig(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) -{ - TIFF* tif = img->tif; - tileContigRoutine put = img->put.contig; - uint32_t row, y, nrow, nrowsub, rowstoread; - tmsize_t pos; - unsigned char* buf = NULL; - uint32_t rowsperstrip; - uint16_t subsamplinghor,subsamplingver; - uint32_t imagewidth = img->width; - tmsize_t scanline; - int32_t fromskew, toskew; - int ret = 1, flip; - tmsize_t maxstripsize; - - TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver); - if( subsamplingver == 0 ) { - TIFFErrorExtR(tif, TIFFFileName(tif), "Invalid vertical YCbCr subsampling"); - return (0); - } - - maxstripsize = TIFFStripSize(tif); - - flip = setorientation(img); - if (flip & FLIP_VERTICALLY) { - if ( w > INT_MAX ) { - TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow"); - return (0); - } - y = h - 1; - toskew = -(int32_t)(w + w); - } else { - y = 0; - toskew = -(int32_t)(w - w); - } - - TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - - scanline = TIFFScanlineSize(tif); - fromskew = (w < imagewidth ? imagewidth - w : 0); - for (row = 0; row < h; row += nrow) - { - uint32_t temp; - rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; - nrow = (row + rowstoread > h ? h - row : rowstoread); - nrowsub = nrow; - if ((nrowsub%subsamplingver)!=0) - nrowsub+=subsamplingver-nrowsub%subsamplingver; - temp = (row + img->row_offset)%rowsperstrip + nrowsub; - if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) ) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "Integer overflow in gtStripContig"); - return 0; - } - if (_TIFFReadEncodedStripAndAllocBuffer(tif, - TIFFComputeStrip(tif,row+img->row_offset, 0), - (void**)(&buf), - maxstripsize, - temp * scanline)==(tmsize_t)(-1) - && (buf == NULL || img->stoponerr)) - { - ret = 0; - break; - } - - pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ - ((tmsize_t) img->col_offset * img->samplesperpixel); - tmsize_t roffset = (tmsize_t) y * w; - (*put)(img, raster + roffset, 0, y, w, nrow, fromskew, toskew, buf + pos); - y += ((flip & FLIP_VERTICALLY) ? -(int32_t) nrow : (int32_t) nrow); - } - - if (flip & FLIP_HORIZONTALLY) { - uint32_t line; - - for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); - uint32_t *right = left + w - 1; - - while ( left < right ) { - uint32_t temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } - } - - _TIFFfreeExt(img->tif, buf); - return (ret); + */ +static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, + uint32_t h) +{ + TIFF *tif = img->tif; + tileContigRoutine put = img->put.contig; + uint32_t row, y, nrow, nrowsub, rowstoread; + tmsize_t pos; + unsigned char *buf = NULL; + uint32_t rowsperstrip; + uint16_t subsamplinghor, subsamplingver; + uint32_t imagewidth = img->width; + tmsize_t scanline; + int32_t fromskew, toskew; + int ret = 1, flip; + tmsize_t maxstripsize; + + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, + &subsamplingver); + if (subsamplingver == 0) + { + TIFFErrorExtR(tif, TIFFFileName(tif), + "Invalid vertical YCbCr subsampling"); + return (0); + } + + maxstripsize = TIFFStripSize(tif); + + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) + { + if (w > INT_MAX) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow"); + return (0); + } + y = h - 1; + toskew = -(int32_t)(w + w); + } + else + { + y = 0; + toskew = -(int32_t)(w - w); + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + + scanline = TIFFScanlineSize(tif); + fromskew = (w < imagewidth ? imagewidth - w : 0); + for (row = 0; row < h; row += nrow) + { + uint32_t temp; + rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; + nrow = (row + rowstoread > h ? h - row : rowstoread); + nrowsub = nrow; + if ((nrowsub % subsamplingver) != 0) + nrowsub += subsamplingver - nrowsub % subsamplingver; + temp = (row + img->row_offset) % rowsperstrip + nrowsub; + if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline)) + { + TIFFErrorExtR(tif, TIFFFileName(tif), + "Integer overflow in gtStripContig"); + return 0; + } + if (_TIFFReadEncodedStripAndAllocBuffer( + tif, TIFFComputeStrip(tif, row + img->row_offset, 0), + (void **)(&buf), maxstripsize, + temp * scanline) == (tmsize_t)(-1) && + (buf == NULL || img->stoponerr)) + { + ret = 0; + break; + } + + pos = ((row + img->row_offset) % rowsperstrip) * scanline + + ((tmsize_t)img->col_offset * img->samplesperpixel); + tmsize_t roffset = (tmsize_t)y * w; + (*put)(img, raster + roffset, 0, y, w, nrow, fromskew, toskew, + buf + pos); + y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + } + + if (flip & FLIP_HORIZONTALLY) + { + uint32_t line; + + for (line = 0; line < h; line++) + { + uint32_t *left = raster + (line * w); + uint32_t *right = left + w - 1; + + while (left < right) + { + uint32_t temp = *left; + *left = *right; + *right = temp; + left++; + right--; + } + } + } + + _TIFFfreeExt(img->tif, buf); + return (ret); } /* @@ -1031,158 +1158,167 @@ gtStripContig(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) * PlanarConfiguration separated * We assume that all such images are RGB. */ -static int -gtStripSeparate(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) -{ - TIFF* tif = img->tif; - tileSeparateRoutine put = img->put.separate; - unsigned char *buf = NULL; - unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL; - uint32_t row, y, nrow, rowstoread; - tmsize_t pos; - tmsize_t scanline; - uint32_t rowsperstrip, offset_row; - uint32_t imagewidth = img->width; - tmsize_t stripsize; - tmsize_t bufsize; - int32_t fromskew, toskew; - int alpha = img->alpha; - int ret = 1, flip; - uint16_t colorchannels; - - stripsize = TIFFStripSize(tif); - bufsize = _TIFFMultiplySSize(tif,alpha?4:3,stripsize, "gtStripSeparate"); - if (bufsize == 0) { - return (0); - } - - flip = setorientation(img); - if (flip & FLIP_VERTICALLY) { - if ( w > INT_MAX ) { - TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow"); - return (0); - } - y = h - 1; - toskew = -(int32_t)(w + w); - } - else { - y = 0; - toskew = -(int32_t)(w - w); - } - - switch( img->photometric ) +static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, + uint32_t h) +{ + TIFF *tif = img->tif; + tileSeparateRoutine put = img->put.separate; + unsigned char *buf = NULL; + unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL; + uint32_t row, y, nrow, rowstoread; + tmsize_t pos; + tmsize_t scanline; + uint32_t rowsperstrip, offset_row; + uint32_t imagewidth = img->width; + tmsize_t stripsize; + tmsize_t bufsize; + int32_t fromskew, toskew; + int alpha = img->alpha; + int ret = 1, flip; + uint16_t colorchannels; + + stripsize = TIFFStripSize(tif); + bufsize = + _TIFFMultiplySSize(tif, alpha ? 4 : 3, stripsize, "gtStripSeparate"); + if (bufsize == 0) + { + return (0); + } + + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) + { + if (w > INT_MAX) { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_PALETTE: + TIFFErrorExtR(tif, TIFFFileName(tif), "Width overflow"); + return (0); + } + y = h - 1; + toskew = -(int32_t)(w + w); + } + else + { + y = 0; + toskew = -(int32_t)(w - w); + } + + switch (img->photometric) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_PALETTE: colorchannels = 1; break; - default: + default: colorchannels = 3; break; + } + + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); + scanline = TIFFScanlineSize(tif); + fromskew = (w < imagewidth ? imagewidth - w : 0); + for (row = 0; row < h; row += nrow) + { + uint32_t temp; + rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; + nrow = (row + rowstoread > h ? h - row : rowstoread); + offset_row = row + img->row_offset; + temp = (row + img->row_offset) % rowsperstrip + nrow; + if (scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline)) + { + TIFFErrorExtR(tif, TIFFFileName(tif), + "Integer overflow in gtStripSeparate"); + return 0; + } + if (buf == NULL) + { + if (_TIFFReadEncodedStripAndAllocBuffer( + tif, TIFFComputeStrip(tif, offset_row, 0), (void **)&buf, + bufsize, temp * scanline) == (tmsize_t)(-1) && + (buf == NULL || img->stoponerr)) + { + ret = 0; + break; + } + p0 = buf; + if (colorchannels == 1) + { + p2 = p1 = p0; + pa = (alpha ? (p0 + 3 * stripsize) : NULL); + } + else + { + p1 = p0 + stripsize; + p2 = p1 + stripsize; + pa = (alpha ? (p2 + stripsize) : NULL); + } + } + else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), + p0, temp * scanline) == (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 && + TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), p1, + temp * scanline) == (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (colorchannels > 1 && + TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), p2, + temp * scanline) == (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } + if (alpha) + { + if (TIFFReadEncodedStrip( + tif, TIFFComputeStrip(tif, offset_row, colorchannels), pa, + temp * scanline) == (tmsize_t)(-1) && + img->stoponerr) + { + ret = 0; + break; + } } - TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - scanline = TIFFScanlineSize(tif); - fromskew = (w < imagewidth ? imagewidth - w : 0); - for (row = 0; row < h; row += nrow) - { - uint32_t temp; - rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; - nrow = (row + rowstoread > h ? h - row : rowstoread); - offset_row = row + img->row_offset; - temp = (row + img->row_offset)%rowsperstrip + nrow; - if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) ) - { - TIFFErrorExtR(tif, TIFFFileName(tif), "Integer overflow in gtStripSeparate"); - return 0; - } - if( buf == NULL ) - { - if (_TIFFReadEncodedStripAndAllocBuffer( - tif, TIFFComputeStrip(tif, offset_row, 0), - (void**) &buf, bufsize, - temp * scanline)==(tmsize_t)(-1) - && (buf == NULL || img->stoponerr)) - { - ret = 0; - break; - } - p0 = buf; - if( colorchannels == 1 ) - { - p2 = p1 = p0; - pa = (alpha?(p0+3*stripsize):NULL); - } - else - { - p1 = p0 + stripsize; - p2 = p1 + stripsize; - pa = (alpha?(p2+stripsize):NULL); - } - } - else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0), - p0, temp * scanline)==(tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 - && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1), - p1, temp * scanline) == (tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - if (colorchannels > 1 - && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2), - p2, temp * scanline) == (tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - if (alpha) - { - if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels), - pa, temp * scanline)==(tmsize_t)(-1) - && img->stoponerr) - { - ret = 0; - break; - } - } - - pos = ((row + img->row_offset) % rowsperstrip) * scanline + \ - ((tmsize_t) img->col_offset * img->samplesperpixel); - tmsize_t roffset = (tmsize_t) y * w; - (*put)(img, raster + roffset, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos, - p2 + pos, (alpha?(pa+pos):NULL)); - y += ((flip & FLIP_VERTICALLY) ? -(int32_t) nrow : (int32_t) nrow); - } - - if (flip & FLIP_HORIZONTALLY) { - uint32_t line; - - for (line = 0; line < h; line++) { - uint32_t *left = raster + (line * w); - uint32_t *right = left + w - 1; - - while ( left < right ) { - uint32_t temp = *left; - *left = *right; - *right = temp; - left++; - right--; - } - } - } - - _TIFFfreeExt(img->tif, buf); - return (ret); + pos = ((row + img->row_offset) % rowsperstrip) * scanline + + ((tmsize_t)img->col_offset * img->samplesperpixel); + tmsize_t roffset = (tmsize_t)y * w; + (*put)(img, raster + roffset, 0, y, w, nrow, fromskew, toskew, p0 + pos, + p1 + pos, p2 + pos, (alpha ? (pa + pos) : NULL)); + y += ((flip & FLIP_VERTICALLY) ? -(int32_t)nrow : (int32_t)nrow); + } + + if (flip & FLIP_HORIZONTALLY) + { + uint32_t line; + + for (line = 0; line < h; line++) + { + uint32_t *left = raster + (line * w); + uint32_t *right = left + w - 1; + + while (left < right) + { + uint32_t temp = *left; + *left = *right; + *right = temp; + left++; + right--; + } + } + } + + _TIFFfreeExt(img->tif, buf); + return (ret); } /* @@ -1195,98 +1331,139 @@ gtStripSeparate(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h) * PickSeparateCase analyze the parameters and select * the appropriate "get" and "put" routine to use. */ -#define REPEAT8(op) REPEAT4(op); REPEAT4(op) -#define REPEAT4(op) REPEAT2(op); REPEAT2(op) -#define REPEAT2(op) op; op -#define CASE8(x,op) \ - switch (x) { \ - case 7: op; /*-fallthrough*/ \ - case 6: op; /*-fallthrough*/ \ - case 5: op; /*-fallthrough*/ \ - case 4: op; /*-fallthrough*/ \ - case 3: op; /*-fallthrough*/ \ - case 2: op; /*-fallthrough*/ \ - case 1: op; \ - } -#define CASE4(x,op) switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; } -#define NOP - -#define UNROLL8(w, op1, op2) { \ - uint32_t _x; \ - for (_x = w; _x >= 8; _x -= 8) { \ - op1; \ - REPEAT8(op2); \ - } \ - if (_x > 0) { \ - op1; \ - CASE8(_x,op2); \ - } \ -} -#define UNROLL4(w, op1, op2) { \ - uint32_t _x; \ - for (_x = w; _x >= 4; _x -= 4) { \ - op1; \ - REPEAT4(op2); \ - } \ - if (_x > 0) { \ - op1; \ - CASE4(_x,op2); \ - } \ -} -#define UNROLL2(w, op1, op2) { \ - uint32_t _x; \ - for (_x = w; _x >= 2; _x -= 2) { \ - op1; \ - REPEAT2(op2); \ - } \ - if (_x) { \ - op1; \ - op2; \ - } \ -} - -#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; } -#define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; } - -#define A1 (((uint32_t)0xffL)<<24) -#define PACK(r,g,b) \ - ((uint32_t)(r)|((uint32_t)(g)<<8)|((uint32_t)(b)<<16)|A1) -#define PACK4(r,g,b,a) \ - ((uint32_t)(r)|((uint32_t)(g)<<8)|((uint32_t)(b)<<16)|((uint32_t)(a)<<24)) -#define W2B(v) (((v)>>8)&0xff) +#define REPEAT8(op) \ + REPEAT4(op); \ + REPEAT4(op) +#define REPEAT4(op) \ + REPEAT2(op); \ + REPEAT2(op) +#define REPEAT2(op) \ + op; \ + op +#define CASE8(x, op) \ + switch (x) \ + { \ + case 7: \ + op; /*-fallthrough*/ \ + case 6: \ + op; /*-fallthrough*/ \ + case 5: \ + op; /*-fallthrough*/ \ + case 4: \ + op; /*-fallthrough*/ \ + case 3: \ + op; /*-fallthrough*/ \ + case 2: \ + op; /*-fallthrough*/ \ + case 1: \ + op; \ + } +#define CASE4(x, op) \ + switch (x) \ + { \ + case 3: \ + op; /*-fallthrough*/ \ + case 2: \ + op; /*-fallthrough*/ \ + case 1: \ + op; \ + } +#define NOP + +#define UNROLL8(w, op1, op2) \ + { \ + uint32_t _x; \ + for (_x = w; _x >= 8; _x -= 8) \ + { \ + op1; \ + REPEAT8(op2); \ + } \ + if (_x > 0) \ + { \ + op1; \ + CASE8(_x, op2); \ + } \ + } +#define UNROLL4(w, op1, op2) \ + { \ + uint32_t _x; \ + for (_x = w; _x >= 4; _x -= 4) \ + { \ + op1; \ + REPEAT4(op2); \ + } \ + if (_x > 0) \ + { \ + op1; \ + CASE4(_x, op2); \ + } \ + } +#define UNROLL2(w, op1, op2) \ + { \ + uint32_t _x; \ + for (_x = w; _x >= 2; _x -= 2) \ + { \ + op1; \ + REPEAT2(op2); \ + } \ + if (_x) \ + { \ + op1; \ + op2; \ + } \ + } + +#define SKEW(r, g, b, skew) \ + { \ + r += skew; \ + g += skew; \ + b += skew; \ + } +#define SKEW4(r, g, b, a, skew) \ + { \ + r += skew; \ + g += skew; \ + b += skew; \ + a += skew; \ + } + +#define A1 (((uint32_t)0xffL) << 24) +#define PACK(r, g, b) \ + ((uint32_t)(r) | ((uint32_t)(g) << 8) | ((uint32_t)(b) << 16) | A1) +#define PACK4(r, g, b, a) \ + ((uint32_t)(r) | ((uint32_t)(g) << 8) | ((uint32_t)(b) << 16) | \ + ((uint32_t)(a) << 24)) +#define W2B(v) (((v) >> 8) & 0xff) /* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */ -#define PACKW(r,g,b) \ - ((uint32_t)W2B(r)|((uint32_t)W2B(g)<<8)|((uint32_t)W2B(b)<<16)|A1) -#define PACKW4(r,g,b,a) \ - ((uint32_t)W2B(r)|((uint32_t)W2B(g)<<8)|((uint32_t)W2B(b)<<16)|((uint32_t)W2B(a)<<24)) - -#define DECLAREContigPutFunc(name) \ -static void name(\ - TIFFRGBAImage* img, \ - uint32_t* cp, \ - uint32_t x, uint32_t y, \ - uint32_t w, uint32_t h, \ - int32_t fromskew, int32_t toskew, \ - unsigned char* pp \ -) +#define PACKW(r, g, b) \ + ((uint32_t)W2B(r) | ((uint32_t)W2B(g) << 8) | ((uint32_t)W2B(b) << 16) | A1) +#define PACKW4(r, g, b, a) \ + ((uint32_t)W2B(r) | ((uint32_t)W2B(g) << 8) | ((uint32_t)W2B(b) << 16) | \ + ((uint32_t)W2B(a) << 24)) + +#define DECLAREContigPutFunc(name) \ + static void name(TIFFRGBAImage *img, uint32_t *cp, uint32_t x, uint32_t y, \ + uint32_t w, uint32_t h, int32_t fromskew, int32_t toskew, \ + unsigned char *pp) /* * 8-bit palette => colormap/RGB */ DECLAREContigPutFunc(put8bitcmaptile) { - uint32_t** PALmap = img->PALmap; + uint32_t **PALmap = img->PALmap; int samplesperpixel = img->samplesperpixel; - (void) y; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) + (void)y; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) { - *cp++ = PALmap[*pp][0]; + *cp++ = PALmap[*pp][0]; pp += samplesperpixel; } - cp += toskew; - pp += fromskew; + cp += toskew; + pp += fromskew; } } @@ -1295,15 +1472,17 @@ DECLAREContigPutFunc(put8bitcmaptile) */ DECLAREContigPutFunc(put4bitcmaptile) { - uint32_t** PALmap = img->PALmap; + uint32_t **PALmap = img->PALmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 2; - for( ; h > 0; --h) { - uint32_t* bw; - UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1312,15 +1491,17 @@ DECLAREContigPutFunc(put4bitcmaptile) */ DECLAREContigPutFunc(put2bitcmaptile) { - uint32_t** PALmap = img->PALmap; + uint32_t **PALmap = img->PALmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 4; - for( ; h > 0; --h) { - uint32_t* bw; - UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1329,15 +1510,17 @@ DECLAREContigPutFunc(put2bitcmaptile) */ DECLAREContigPutFunc(put1bitcmaptile) { - uint32_t** PALmap = img->PALmap; + uint32_t **PALmap = img->PALmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 8; - for( ; h > 0; --h) { - uint32_t* bw; - UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1347,17 +1530,18 @@ DECLAREContigPutFunc(put1bitcmaptile) DECLAREContigPutFunc(putgreytile) { int samplesperpixel = img->samplesperpixel; - uint32_t** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) y; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) + (void)y; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) { - *cp++ = BWmap[*pp][0]; + *cp++ = BWmap[*pp][0]; pp += samplesperpixel; } - cp += toskew; - pp += fromskew; + cp += toskew; + pp += fromskew; } } @@ -1367,17 +1551,18 @@ DECLAREContigPutFunc(putgreytile) DECLAREContigPutFunc(putagreytile) { int samplesperpixel = img->samplesperpixel; - uint32_t** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) y; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) + (void)y; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) { - *cp++ = BWmap[*pp][0] & ((uint32_t)*(pp + 1) << 24 | ~A1); + *cp++ = BWmap[*pp][0] & ((uint32_t) * (pp + 1) << 24 | ~A1); pp += samplesperpixel; } - cp += toskew; - pp += fromskew; + cp += toskew; + pp += fromskew; } } @@ -1387,22 +1572,23 @@ DECLAREContigPutFunc(putagreytile) DECLAREContigPutFunc(put16bitbwtile) { int samplesperpixel = img->samplesperpixel; - uint32_t** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) y; - for( ; h > 0; --h) { - uint16_t *wp = (uint16_t *) pp; + (void)y; + for (; h > 0; --h) + { + uint16_t *wp = (uint16_t *)pp; - for (x = w; x > 0; --x) + for (x = w; x > 0; --x) { /* use high order byte of 16bit value */ - *cp++ = BWmap[*wp >> 8][0]; + *cp++ = BWmap[*wp >> 8][0]; pp += 2 * samplesperpixel; wp += samplesperpixel; } - cp += toskew; - pp += fromskew; + cp += toskew; + pp += fromskew; } } @@ -1411,15 +1597,17 @@ DECLAREContigPutFunc(put16bitbwtile) */ DECLAREContigPutFunc(put1bitbwtile) { - uint32_t** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 8; - for( ; h > 0; --h) { - uint32_t* bw; - UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1428,15 +1616,17 @@ DECLAREContigPutFunc(put1bitbwtile) */ DECLAREContigPutFunc(put2bitbwtile) { - uint32_t** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 4; - for( ; h > 0; --h) { - uint32_t* bw; - UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1445,15 +1635,17 @@ DECLAREContigPutFunc(put2bitbwtile) */ DECLAREContigPutFunc(put4bitbwtile) { - uint32_t** BWmap = img->BWmap; + uint32_t **BWmap = img->BWmap; - (void) x; (void) y; + (void)x; + (void)y; fromskew /= 2; - for( ; h > 0; --h) { - uint32_t* bw; - UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + uint32_t *bw; + UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++); + cp += toskew; + pp += fromskew; } } @@ -1464,14 +1656,15 @@ DECLAREContigPutFunc(putRGBcontig8bittile) { int samplesperpixel = img->samplesperpixel; - (void) x; (void) y; + (void)x; + (void)y; fromskew *= samplesperpixel; - for( ; h > 0; --h) { - UNROLL8(w, NOP, - *cp++ = PACK(pp[0], pp[1], pp[2]); - pp += samplesperpixel); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + UNROLL8(w, NOP, *cp++ = PACK(pp[0], pp[1], pp[2]); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; } } @@ -1483,14 +1676,15 @@ DECLAREContigPutFunc(putRGBAAcontig8bittile) { int samplesperpixel = img->samplesperpixel; - (void) x; (void) y; + (void)x; + (void)y; fromskew *= samplesperpixel; - for( ; h > 0; --h) { - UNROLL8(w, NOP, - *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); - pp += samplesperpixel); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + UNROLL8(w, NOP, *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]); + pp += samplesperpixel); + cp += toskew; + pp += fromskew; } } @@ -1500,24 +1694,26 @@ DECLAREContigPutFunc(putRGBAAcontig8bittile) */ DECLAREContigPutFunc(putRGBUAcontig8bittile) { - int samplesperpixel = img->samplesperpixel; - (void) y; - fromskew *= samplesperpixel; - for( ; h > 0; --h) { - uint32_t r, g, b, a; - uint8_t* m; - for (x = w; x > 0; --x) { - a = pp[3]; - m = img->UaToAa+((size_t) a<<8); - r = m[pp[0]]; - g = m[pp[1]]; - b = m[pp[2]]; - *cp++ = PACK4(r,g,b,a); - pp += samplesperpixel; - } - cp += toskew; - pp += fromskew; - } + int samplesperpixel = img->samplesperpixel; + (void)y; + fromskew *= samplesperpixel; + for (; h > 0; --h) + { + uint32_t r, g, b, a; + uint8_t *m; + for (x = w; x > 0; --x) + { + a = pp[3]; + m = img->UaToAa + ((size_t)a << 8); + r = m[pp[0]]; + g = m[pp[1]]; + b = m[pp[2]]; + *cp++ = PACK4(r, g, b, a); + pp += samplesperpixel; + } + cp += toskew; + pp += fromskew; + } } /* @@ -1525,20 +1721,21 @@ DECLAREContigPutFunc(putRGBUAcontig8bittile) */ DECLAREContigPutFunc(putRGBcontig16bittile) { - int samplesperpixel = img->samplesperpixel; - uint16_t *wp = (uint16_t *)pp; - (void) y; - fromskew *= samplesperpixel; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) { - *cp++ = PACK(img->Bitdepth16To8[wp[0]], - img->Bitdepth16To8[wp[1]], - img->Bitdepth16To8[wp[2]]); - wp += samplesperpixel; - } - cp += toskew; - wp += fromskew; - } + int samplesperpixel = img->samplesperpixel; + uint16_t *wp = (uint16_t *)pp; + (void)y; + fromskew *= samplesperpixel; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) + { + *cp++ = PACK(img->Bitdepth16To8[wp[0]], img->Bitdepth16To8[wp[1]], + img->Bitdepth16To8[wp[2]]); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } } /* @@ -1547,21 +1744,21 @@ DECLAREContigPutFunc(putRGBcontig16bittile) */ DECLAREContigPutFunc(putRGBAAcontig16bittile) { - int samplesperpixel = img->samplesperpixel; - uint16_t *wp = (uint16_t *)pp; - (void) y; - fromskew *= samplesperpixel; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) { - *cp++ = PACK4(img->Bitdepth16To8[wp[0]], - img->Bitdepth16To8[wp[1]], - img->Bitdepth16To8[wp[2]], - img->Bitdepth16To8[wp[3]]); - wp += samplesperpixel; - } - cp += toskew; - wp += fromskew; - } + int samplesperpixel = img->samplesperpixel; + uint16_t *wp = (uint16_t *)pp; + (void)y; + fromskew *= samplesperpixel; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) + { + *cp++ = PACK4(img->Bitdepth16To8[wp[0]], img->Bitdepth16To8[wp[1]], + img->Bitdepth16To8[wp[2]], img->Bitdepth16To8[wp[3]]); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } } /* @@ -1570,25 +1767,27 @@ DECLAREContigPutFunc(putRGBAAcontig16bittile) */ DECLAREContigPutFunc(putRGBUAcontig16bittile) { - int samplesperpixel = img->samplesperpixel; - uint16_t *wp = (uint16_t *)pp; - (void) y; - fromskew *= samplesperpixel; - for( ; h > 0; --h) { - uint32_t r,g,b,a; - uint8_t* m; - for (x = w; x > 0; --x) { - a = img->Bitdepth16To8[wp[3]]; - m = img->UaToAa+((size_t) a<<8); - r = m[img->Bitdepth16To8[wp[0]]]; - g = m[img->Bitdepth16To8[wp[1]]]; - b = m[img->Bitdepth16To8[wp[2]]]; - *cp++ = PACK4(r,g,b,a); - wp += samplesperpixel; - } - cp += toskew; - wp += fromskew; - } + int samplesperpixel = img->samplesperpixel; + uint16_t *wp = (uint16_t *)pp; + (void)y; + fromskew *= samplesperpixel; + for (; h > 0; --h) + { + uint32_t r, g, b, a; + uint8_t *m; + for (x = w; x > 0; --x) + { + a = img->Bitdepth16To8[wp[3]]; + m = img->UaToAa + ((size_t)a << 8); + r = m[img->Bitdepth16To8[wp[0]]]; + g = m[img->Bitdepth16To8[wp[1]]]; + b = m[img->Bitdepth16To8[wp[2]]]; + *cp++ = PACK4(r, g, b, a); + wp += samplesperpixel; + } + cp += toskew; + wp += fromskew; + } } /* @@ -1601,18 +1800,16 @@ DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) int samplesperpixel = img->samplesperpixel; uint16_t r, g, b, k; - (void) x; (void) y; + (void)x; + (void)y; fromskew *= samplesperpixel; - for( ; h > 0; --h) { - UNROLL8(w, NOP, - k = 255 - pp[3]; - r = (k*(255-pp[0]))/255; - g = (k*(255-pp[1]))/255; - b = (k*(255-pp[2]))/255; - *cp++ = PACK(r, g, b); - pp += samplesperpixel); - cp += toskew; - pp += fromskew; + for (; h > 0; --h) + { + UNROLL8(w, NOP, k = 255 - pp[3]; r = (k * (255 - pp[0])) / 255; + g = (k * (255 - pp[1])) / 255; b = (k * (255 - pp[2])) / 255; + *cp++ = PACK(r, g, b); pp += samplesperpixel); + cp += toskew; + pp += fromskew; } } @@ -1624,45 +1821,47 @@ DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) { int samplesperpixel = img->samplesperpixel; - TIFFRGBValue* Map = img->Map; + TIFFRGBValue *Map = img->Map; uint16_t r, g, b, k; - (void) y; + (void)y; fromskew *= samplesperpixel; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) { - k = 255 - pp[3]; - r = (k*(255-pp[0]))/255; - g = (k*(255-pp[1]))/255; - b = (k*(255-pp[2]))/255; - *cp++ = PACK(Map[r], Map[g], Map[b]); - pp += samplesperpixel; - } - pp += fromskew; - cp += toskew; - } -} - -#define DECLARESepPutFunc(name) \ -static void name(\ - TIFFRGBAImage* img,\ - uint32_t* cp,\ - uint32_t x, uint32_t y, \ - uint32_t w, uint32_t h,\ - int32_t fromskew, int32_t toskew,\ - unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\ -) + for (; h > 0; --h) + { + for (x = w; x > 0; --x) + { + k = 255 - pp[3]; + r = (k * (255 - pp[0])) / 255; + g = (k * (255 - pp[1])) / 255; + b = (k * (255 - pp[2])) / 255; + *cp++ = PACK(Map[r], Map[g], Map[b]); + pp += samplesperpixel; + } + pp += fromskew; + cp += toskew; + } +} + +#define DECLARESepPutFunc(name) \ + static void name(TIFFRGBAImage *img, uint32_t *cp, uint32_t x, uint32_t y, \ + uint32_t w, uint32_t h, int32_t fromskew, int32_t toskew, \ + unsigned char *r, unsigned char *g, unsigned char *b, \ + unsigned char *a) /* * 8-bit unpacked samples => RGB */ DECLARESepPutFunc(putRGBseparate8bittile) { - (void) img; (void) x; (void) y; (void) a; - for( ; h > 0; --h) { - UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); - SKEW(r, g, b, fromskew); - cp += toskew; + (void)img; + (void)x; + (void)y; + (void)a; + for (; h > 0; --h) + { + UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++)); + SKEW(r, g, b, fromskew); + cp += toskew; } } @@ -1671,12 +1870,15 @@ DECLARESepPutFunc(putRGBseparate8bittile) */ DECLARESepPutFunc(putRGBAAseparate8bittile) { - (void) img; (void) x; (void) y; - for( ; h > 0; --h) { - UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); - SKEW4(r, g, b, a, fromskew); - cp += toskew; - } + (void)img; + (void)x; + (void)y; + for (; h > 0; --h) + { + UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++)); + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } } /* @@ -1684,19 +1886,22 @@ DECLARESepPutFunc(putRGBAAseparate8bittile) */ DECLARESepPutFunc(putCMYKseparate8bittile) { - (void) img; (void) y; - for( ; h > 0; --h) { - uint32_t rv, gv, bv, kv; - for (x = w; x > 0; --x) { - kv = 255 - *a++; - rv = (kv*(255-*r++))/255; - gv = (kv*(255-*g++))/255; - bv = (kv*(255-*b++))/255; - *cp++ = PACK4(rv,gv,bv,255); - } - SKEW4(r, g, b, a, fromskew); - cp += toskew; - } + (void)img; + (void)y; + for (; h > 0; --h) + { + uint32_t rv, gv, bv, kv; + for (x = w; x > 0; --x) + { + kv = 255 - *a++; + rv = (kv * (255 - *r++)) / 255; + gv = (kv * (255 - *g++)) / 255; + bv = (kv * (255 - *b++)) / 255; + *cp++ = PACK4(rv, gv, bv, 255); + } + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } } /* @@ -1704,21 +1909,24 @@ DECLARESepPutFunc(putCMYKseparate8bittile) */ DECLARESepPutFunc(putRGBUAseparate8bittile) { - (void) img; (void) y; - for( ; h > 0; --h) { - uint32_t rv, gv, bv, av; - uint8_t* m; - for (x = w; x > 0; --x) { - av = *a++; - m = img->UaToAa+((size_t) av<<8); - rv = m[*r++]; - gv = m[*g++]; - bv = m[*b++]; - *cp++ = PACK4(rv,gv,bv,av); - } - SKEW4(r, g, b, a, fromskew); - cp += toskew; - } + (void)img; + (void)y; + for (; h > 0; --h) + { + uint32_t rv, gv, bv, av; + uint8_t *m; + for (x = w; x > 0; --x) + { + av = *a++; + m = img->UaToAa + ((size_t)av << 8); + rv = m[*r++]; + gv = m[*g++]; + bv = m[*b++]; + *cp++ = PACK4(rv, gv, bv, av); + } + SKEW4(r, g, b, a, fromskew); + cp += toskew; + } } /* @@ -1726,18 +1934,20 @@ DECLARESepPutFunc(putRGBUAseparate8bittile) */ DECLARESepPutFunc(putRGBseparate16bittile) { - uint16_t *wr = (uint16_t*) r; - uint16_t *wg = (uint16_t*) g; - uint16_t *wb = (uint16_t*) b; - (void) img; (void) y; (void) a; - for( ; h > 0; --h) { - for (x = 0; x < w; x++) - *cp++ = PACK(img->Bitdepth16To8[*wr++], - img->Bitdepth16To8[*wg++], - img->Bitdepth16To8[*wb++]); - SKEW(wr, wg, wb, fromskew); - cp += toskew; - } + uint16_t *wr = (uint16_t *)r; + uint16_t *wg = (uint16_t *)g; + uint16_t *wb = (uint16_t *)b; + (void)img; + (void)y; + (void)a; + for (; h > 0; --h) + { + for (x = 0; x < w; x++) + *cp++ = PACK(img->Bitdepth16To8[*wr++], img->Bitdepth16To8[*wg++], + img->Bitdepth16To8[*wb++]); + SKEW(wr, wg, wb, fromskew); + cp += toskew; + } } /* @@ -1745,20 +1955,20 @@ DECLARESepPutFunc(putRGBseparate16bittile) */ DECLARESepPutFunc(putRGBAAseparate16bittile) { - uint16_t *wr = (uint16_t*) r; - uint16_t *wg = (uint16_t*) g; - uint16_t *wb = (uint16_t*) b; - uint16_t *wa = (uint16_t*) a; - (void) img; (void) y; - for( ; h > 0; --h) { - for (x = 0; x < w; x++) - *cp++ = PACK4(img->Bitdepth16To8[*wr++], - img->Bitdepth16To8[*wg++], - img->Bitdepth16To8[*wb++], - img->Bitdepth16To8[*wa++]); - SKEW4(wr, wg, wb, wa, fromskew); - cp += toskew; - } + uint16_t *wr = (uint16_t *)r; + uint16_t *wg = (uint16_t *)g; + uint16_t *wb = (uint16_t *)b; + uint16_t *wa = (uint16_t *)a; + (void)img; + (void)y; + for (; h > 0; --h) + { + for (x = 0; x < w; x++) + *cp++ = PACK4(img->Bitdepth16To8[*wr++], img->Bitdepth16To8[*wg++], + img->Bitdepth16To8[*wb++], img->Bitdepth16To8[*wa++]); + SKEW4(wr, wg, wb, wa, fromskew); + cp += toskew; + } } /* @@ -1766,25 +1976,28 @@ DECLARESepPutFunc(putRGBAAseparate16bittile) */ DECLARESepPutFunc(putRGBUAseparate16bittile) { - uint16_t *wr = (uint16_t*) r; - uint16_t *wg = (uint16_t*) g; - uint16_t *wb = (uint16_t*) b; - uint16_t *wa = (uint16_t*) a; - (void) img; (void) y; - for( ; h > 0; --h) { - uint32_t r2,g2,b2,a2; - uint8_t* m; - for (x = w; x > 0; --x) { - a2 = img->Bitdepth16To8[*wa++]; - m = img->UaToAa+((size_t) a2<<8); - r2 = m[img->Bitdepth16To8[*wr++]]; - g2 = m[img->Bitdepth16To8[*wg++]]; - b2 = m[img->Bitdepth16To8[*wb++]]; - *cp++ = PACK4(r2,g2,b2,a2); - } - SKEW4(wr, wg, wb, wa, fromskew); - cp += toskew; - } + uint16_t *wr = (uint16_t *)r; + uint16_t *wg = (uint16_t *)g; + uint16_t *wb = (uint16_t *)b; + uint16_t *wa = (uint16_t *)a; + (void)img; + (void)y; + for (; h > 0; --h) + { + uint32_t r2, g2, b2, a2; + uint8_t *m; + for (x = w; x > 0; --x) + { + a2 = img->Bitdepth16To8[*wa++]; + m = img->UaToAa + ((size_t)a2 << 8); + r2 = m[img->Bitdepth16To8[*wr++]]; + g2 = m[img->Bitdepth16To8[*wg++]]; + b2 = m[img->Bitdepth16To8[*wb++]]; + *cp++ = PACK4(r2, g2, b2, a2); + } + SKEW4(wr, wg, wb, wa, fromskew); + cp += toskew; + } } /* @@ -1792,24 +2005,23 @@ DECLARESepPutFunc(putRGBUAseparate16bittile) */ DECLAREContigPutFunc(putcontig8bitCIELab8) { - float X, Y, Z; - uint32_t r, g, b; - (void) y; - fromskew *= 3; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) { - TIFFCIELabToXYZ(img->cielab, - (unsigned char)pp[0], - (signed char)pp[1], - (signed char)pp[2], - &X, &Y, &Z); - TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); - *cp++ = PACK(r, g, b); - pp += 3; - } - cp += toskew; - pp += fromskew; - } + float X, Y, Z; + uint32_t r, g, b; + (void)y; + fromskew *= 3; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) + { + TIFFCIELabToXYZ(img->cielab, (unsigned char)pp[0], + (signed char)pp[1], (signed char)pp[2], &X, &Y, &Z); + TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); + *cp++ = PACK(r, g, b); + pp += 3; + } + cp += toskew; + pp += fromskew; + } } /* @@ -1817,67 +2029,70 @@ DECLAREContigPutFunc(putcontig8bitCIELab8) */ DECLAREContigPutFunc(putcontig8bitCIELab16) { - float X, Y, Z; - uint32_t r, g, b; - uint16_t *wp = (uint16_t *)pp; - (void) y; - fromskew *= 3; - for( ; h > 0; --h) { - for (x = w; x > 0; --x) { - TIFFCIELab16ToXYZ(img->cielab, - (uint16_t)wp[0], - (int16_t)wp[1], - (int16_t)wp[2], - &X, &Y, &Z); - TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); - *cp++ = PACK(r, g, b); - wp += 3; - } - cp += toskew; - wp += fromskew; - } + float X, Y, Z; + uint32_t r, g, b; + uint16_t *wp = (uint16_t *)pp; + (void)y; + fromskew *= 3; + for (; h > 0; --h) + { + for (x = w; x > 0; --x) + { + TIFFCIELab16ToXYZ(img->cielab, (uint16_t)wp[0], (int16_t)wp[1], + (int16_t)wp[2], &X, &Y, &Z); + TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b); + *cp++ = PACK(r, g, b); + wp += 3; + } + cp += toskew; + wp += fromskew; + } } /* * YCbCr -> RGB conversion and packing routines. */ -#define YCbCrtoRGB(dst, Y) { \ - uint32_t r, g, b; \ - TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ - dst = PACK(r, g, b); \ -} +#define YCbCrtoRGB(dst, Y) \ + { \ + uint32_t r, g, b; \ + TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \ + dst = PACK(r, g, b); \ + } /* * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB */ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) { - uint32_t* cp1 = cp + w + toskew; - uint32_t* cp2 = cp1 + w + toskew; - uint32_t* cp3 = cp2 + w + toskew; + uint32_t *cp1 = cp + w + toskew; + uint32_t *cp2 = cp1 + w + toskew; + uint32_t *cp3 = cp2 + w + toskew; int32_t incr = 3 * w + 4 * toskew; - (void) y; + (void)y; /* adjust fromskew */ - fromskew = (fromskew / 4) * (4*2+2); - if ((h & 3) == 0 && (w & 3) == 0) { - for (; h >= 4; h -= 4) { - x = w>>2; - do { + fromskew = (fromskew / 4) * (4 * 2 + 2); + if ((h & 3) == 0 && (w & 3) == 0) + { + for (; h >= 4; h -= 4) + { + x = w >> 2; + do + { int32_t Cb = pp[16]; int32_t Cr = pp[17]; - YCbCrtoRGB(cp [0], pp[ 0]); - YCbCrtoRGB(cp [1], pp[ 1]); - YCbCrtoRGB(cp [2], pp[ 2]); - YCbCrtoRGB(cp [3], pp[ 3]); - YCbCrtoRGB(cp1[0], pp[ 4]); - YCbCrtoRGB(cp1[1], pp[ 5]); - YCbCrtoRGB(cp1[2], pp[ 6]); - YCbCrtoRGB(cp1[3], pp[ 7]); - YCbCrtoRGB(cp2[0], pp[ 8]); - YCbCrtoRGB(cp2[1], pp[ 9]); + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp[2], pp[2]); + YCbCrtoRGB(cp[3], pp[3]); + YCbCrtoRGB(cp1[0], pp[4]); + YCbCrtoRGB(cp1[1], pp[5]); + YCbCrtoRGB(cp1[2], pp[6]); + YCbCrtoRGB(cp1[3], pp[7]); + YCbCrtoRGB(cp2[0], pp[8]); + YCbCrtoRGB(cp2[1], pp[9]); YCbCrtoRGB(cp2[2], pp[10]); YCbCrtoRGB(cp2[3], pp[11]); YCbCrtoRGB(cp3[0], pp[12]); @@ -1897,47 +2112,80 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) cp3 += incr; pp += fromskew; } - } else { - while (h > 0) { - for (x = w; x > 0;) { + } + else + { + while (h > 0) + { + for (x = w; x > 0;) + { int32_t Cb = pp[16]; int32_t Cr = pp[17]; - switch (x) { - default: - switch (h) { - default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */ - case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */ - case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 3: - switch (h) { - default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */ - case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */ - case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 2: - switch (h) { - default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */ - case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */ - case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 1: - switch (h) { - default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */ - case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */ - case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + switch (x) + { + default: + switch (h) + { + default: + YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */ + case 3: + YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */ + case 2: + YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 3: + switch (h) + { + default: + YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */ + case 3: + YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */ + case 2: + YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 2: + switch (h) + { + default: + YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */ + case 3: + YCbCrtoRGB(cp2[1], pp[9]); /* FALLTHROUGH */ + case 2: + YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 1: + switch (h) + { + default: + YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */ + case 3: + YCbCrtoRGB(cp2[0], pp[8]); /* FALLTHROUGH */ + case 2: + YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ } - if (x < 4) { - cp += x; cp1 += x; cp2 += x; cp3 += x; + if (x < 4) + { + cp += x; + cp1 += x; + cp2 += x; + cp3 += x; x = 0; } - else { - cp += 4; cp1 += 4; cp2 += 4; cp3 += 4; + else + { + cp += 4; + cp1 += 4; + cp2 += 4; + cp3 += 4; x -= 4; } pp += 18; @@ -1959,27 +2207,30 @@ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) { - uint32_t* cp1 = cp + w + toskew; + uint32_t *cp1 = cp + w + toskew; int32_t incr = 2 * toskew + w; - (void) y; - fromskew = (fromskew / 4) * (4*2+2); - if ((w & 3) == 0 && (h & 1) == 0) { - for (; h >= 2; h -= 2) { - x = w>>2; - do { + (void)y; + fromskew = (fromskew / 4) * (4 * 2 + 2); + if ((w & 3) == 0 && (h & 1) == 0) + { + for (; h >= 2; h -= 2) + { + x = w >> 2; + do + { int32_t Cb = pp[8]; int32_t Cr = pp[9]; - - YCbCrtoRGB(cp [0], pp[0]); - YCbCrtoRGB(cp [1], pp[1]); - YCbCrtoRGB(cp [2], pp[2]); - YCbCrtoRGB(cp [3], pp[3]); + + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp[2], pp[2]); + YCbCrtoRGB(cp[3], pp[3]); YCbCrtoRGB(cp1[0], pp[4]); YCbCrtoRGB(cp1[1], pp[5]); YCbCrtoRGB(cp1[2], pp[6]); YCbCrtoRGB(cp1[3], pp[7]); - + cp += 4; cp1 += 4; pp += 10; @@ -1988,39 +2239,60 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) cp1 += incr; pp += fromskew; } - } else { - while (h > 0) { - for (x = w; x > 0;) { + } + else + { + while (h > 0) + { + for (x = w; x > 0;) + { int32_t Cb = pp[8]; int32_t Cr = pp[9]; - switch (x) { - default: - switch (h) { - default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 3: - switch (h) { - default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 2: - switch (h) { - default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ - case 1: - switch (h) { - default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */ - case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */ - } /* FALLTHROUGH */ + switch (x) + { + default: + switch (h) + { + default: + YCbCrtoRGB(cp1[3], pp[7]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[3], pp[3]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 3: + switch (h) + { + default: + YCbCrtoRGB(cp1[2], pp[6]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[2], pp[2]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 2: + switch (h) + { + default: + YCbCrtoRGB(cp1[1], pp[5]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[1], pp[1]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ + case 1: + switch (h) + { + default: + YCbCrtoRGB(cp1[0], pp[4]); /* FALLTHROUGH */ + case 1: + YCbCrtoRGB(cp[0], pp[0]); /* FALLTHROUGH */ + } /* FALLTHROUGH */ } - if (x < 4) { - cp += x; cp1 += x; + if (x < 4) + { + cp += x; + cp1 += x; x = 0; } - else { - cp += 4; cp1 += 4; + else + { + cp += 4; + cp1 += 4; x -= 4; } pp += 10; @@ -2040,44 +2312,50 @@ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) { - (void) y; - fromskew = (fromskew / 4) * (4*1+2); - do { - x = w>>2; - while(x>0) { - int32_t Cb = pp[4]; - int32_t Cr = pp[5]; - - YCbCrtoRGB(cp [0], pp[0]); - YCbCrtoRGB(cp [1], pp[1]); - YCbCrtoRGB(cp [2], pp[2]); - YCbCrtoRGB(cp [3], pp[3]); - - cp += 4; - pp += 6; - x--; - } - - if( (w&3) != 0 ) + (void)y; + fromskew = (fromskew / 4) * (4 * 1 + 2); + do + { + x = w >> 2; + while (x > 0) + { + int32_t Cb = pp[4]; + int32_t Cr = pp[5]; + + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp[2], pp[2]); + YCbCrtoRGB(cp[3], pp[3]); + + cp += 4; + pp += 6; + x--; + } + + if ((w & 3) != 0) { - int32_t Cb = pp[4]; - int32_t Cr = pp[5]; - - switch( (w&3) ) { - case 3: YCbCrtoRGB(cp [2], pp[2]); /*-fallthrough*/ - case 2: YCbCrtoRGB(cp [1], pp[1]); /*-fallthrough*/ - case 1: YCbCrtoRGB(cp [0], pp[0]); /*-fallthrough*/ - case 0: break; + int32_t Cb = pp[4]; + int32_t Cr = pp[5]; + + switch ((w & 3)) + { + case 3: + YCbCrtoRGB(cp[2], pp[2]); /*-fallthrough*/ + case 2: + YCbCrtoRGB(cp[1], pp[1]); /*-fallthrough*/ + case 1: + YCbCrtoRGB(cp[0], pp[0]); /*-fallthrough*/ + case 0: + break; } - cp += (w&3); + cp += (w & 3); pp += 6; } - cp += toskew; - pp += fromskew; + cp += toskew; + pp += fromskew; } while (--h); - } /* @@ -2085,57 +2363,63 @@ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) { - uint32_t* cp2; - int32_t incr = 2 * toskew + w; - (void) y; - fromskew = (fromskew / 2) * (2*2+2); - cp2 = cp+w+toskew; - while (h>=2) { - x = w; - while (x>=2) { - uint32_t Cb = pp[4]; - uint32_t Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); - YCbCrtoRGB(cp2[0], pp[2]); - YCbCrtoRGB(cp2[1], pp[3]); - cp += 2; - cp2 += 2; - pp += 6; - x -= 2; - } - if (x==1) { - uint32_t Cb = pp[4]; - uint32_t Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp2[0], pp[2]); - cp ++ ; - cp2 ++ ; - pp += 6; - } - cp += incr; - cp2 += incr; - pp += fromskew; - h-=2; - } - if (h==1) { - x = w; - while (x>=2) { - uint32_t Cb = pp[4]; - uint32_t Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); - cp += 2; - cp2 += 2; - pp += 6; - x -= 2; - } - if (x==1) { - uint32_t Cb = pp[4]; - uint32_t Cr = pp[5]; - YCbCrtoRGB(cp[0], pp[0]); - } - } + uint32_t *cp2; + int32_t incr = 2 * toskew + w; + (void)y; + fromskew = (fromskew / 2) * (2 * 2 + 2); + cp2 = cp + w + toskew; + while (h >= 2) + { + x = w; + while (x >= 2) + { + uint32_t Cb = pp[4]; + uint32_t Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp2[0], pp[2]); + YCbCrtoRGB(cp2[1], pp[3]); + cp += 2; + cp2 += 2; + pp += 6; + x -= 2; + } + if (x == 1) + { + uint32_t Cb = pp[4]; + uint32_t Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp2[0], pp[2]); + cp++; + cp2++; + pp += 6; + } + cp += incr; + cp2 += incr; + pp += fromskew; + h -= 2; + } + if (h == 1) + { + x = w; + while (x >= 2) + { + uint32_t Cb = pp[4]; + uint32_t Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); + cp += 2; + cp2 += 2; + pp += 6; + x -= 2; + } + if (x == 1) + { + uint32_t Cb = pp[4]; + uint32_t Cr = pp[5]; + YCbCrtoRGB(cp[0], pp[0]); + } + } } /* @@ -2143,36 +2427,38 @@ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) { - (void) y; - fromskew = (fromskew / 2) * (2*1+2); - do { - x = w>>1; - while(x>0) { - int32_t Cb = pp[2]; - int32_t Cr = pp[3]; + (void)y; + fromskew = (fromskew / 2) * (2 * 1 + 2); + do + { + x = w >> 1; + while (x > 0) + { + int32_t Cb = pp[2]; + int32_t Cr = pp[3]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp[1], pp[1]); + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[1], pp[1]); - cp += 2; - pp += 4; - x --; - } + cp += 2; + pp += 4; + x--; + } - if( (w&1) != 0 ) - { - int32_t Cb = pp[2]; - int32_t Cr = pp[3]; + if ((w & 1) != 0) + { + int32_t Cb = pp[2]; + int32_t Cr = pp[3]; - YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp[0], pp[0]); - cp += 1; - pp += 4; - } + cp += 1; + pp += 4; + } - cp += toskew; - pp += fromskew; - } while (--h); + cp += toskew; + pp += fromskew; + } while (--h); } /* @@ -2180,37 +2466,41 @@ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) { - uint32_t* cp2; - int32_t incr = 2 * toskew + w; - (void) y; - fromskew = (fromskew / 1) * (1 * 2 + 2); - cp2 = cp+w+toskew; - while (h>=2) { - x = w; - do { - uint32_t Cb = pp[2]; - uint32_t Cr = pp[3]; - YCbCrtoRGB(cp[0], pp[0]); - YCbCrtoRGB(cp2[0], pp[1]); - cp ++; - cp2 ++; - pp += 4; - } while (--x); - cp += incr; - cp2 += incr; - pp += fromskew; - h-=2; - } - if (h==1) { - x = w; - do { - uint32_t Cb = pp[2]; - uint32_t Cr = pp[3]; - YCbCrtoRGB(cp[0], pp[0]); - cp ++; - pp += 4; - } while (--x); - } + uint32_t *cp2; + int32_t incr = 2 * toskew + w; + (void)y; + fromskew = (fromskew / 1) * (1 * 2 + 2); + cp2 = cp + w + toskew; + while (h >= 2) + { + x = w; + do + { + uint32_t Cb = pp[2]; + uint32_t Cr = pp[3]; + YCbCrtoRGB(cp[0], pp[0]); + YCbCrtoRGB(cp2[0], pp[1]); + cp++; + cp2++; + pp += 4; + } while (--x); + cp += incr; + cp2 += incr; + pp += fromskew; + h -= 2; + } + if (h == 1) + { + x = w; + do + { + uint32_t Cb = pp[2]; + uint32_t Cr = pp[3]; + YCbCrtoRGB(cp[0], pp[0]); + cp++; + pp += 4; + } while (--x); + } } /* @@ -2218,21 +2508,23 @@ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) */ DECLAREContigPutFunc(putcontig8bitYCbCr11tile) { - (void) y; - fromskew = (fromskew / 1) * (1 * 1 + 2); - do { - x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ - do { - int32_t Cb = pp[1]; - int32_t Cr = pp[2]; + (void)y; + fromskew = (fromskew / 1) * (1 * 1 + 2); + do + { + x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ + do + { + int32_t Cb = pp[1]; + int32_t Cr = pp[2]; - YCbCrtoRGB(*cp++, pp[0]); + YCbCrtoRGB(*cp++, pp[0]); - pp += 3; - } while (--x); - cp += toskew; - pp += fromskew; - } while (--h); + pp += 3; + } while (--x); + cp += toskew; + pp += fromskew; + } while (--h); } /* @@ -2240,19 +2532,22 @@ DECLAREContigPutFunc(putcontig8bitYCbCr11tile) */ DECLARESepPutFunc(putseparate8bitYCbCr11tile) { - (void) y; - (void) a; - /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */ - for( ; h > 0; --h) { - x = w; - do { - uint32_t dr, dg, db; - TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db); - *cp++ = PACK(dr,dg,db); - } while (--x); - SKEW(r, g, b, fromskew); - cp += toskew; - } + (void)y; + (void)a; + /* TODO: naming of input vars is still off, change obfuscating declaration + * inside define, or resolve obfuscation */ + for (; h > 0; --h) + { + x = w; + do + { + uint32_t dr, dg, db; + TIFFYCbCrtoRGB(img->ycbcr, *r++, *g++, *b++, &dr, &dg, &db); + *cp++ = PACK(dr, dg, db); + } while (--x); + SKEW(r, g, b, fromskew); + cp += toskew; + } } #undef YCbCrtoRGB @@ -2261,101 +2556,100 @@ static int isInRefBlackWhiteRange(float f) return f > (float)(-0x7FFFFFFF + 128) && f < (float)0x7FFFFFFF; } -static int -initYCbCrConversion(TIFFRGBAImage* img) -{ - static const char module[] = "initYCbCrConversion"; - - float *luma, *refBlackWhite; - - if (img->ycbcr == NULL) { - img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmallocExt(img->tif, - TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)) - + 4*256*sizeof (TIFFRGBValue) - + 2*256*sizeof (int) - + 3*256*sizeof (int32_t) - ); - if (img->ycbcr == NULL) { - TIFFErrorExtR(img->tif, module, - "No space for YCbCr->RGB conversion state"); - return (0); - } - } - - TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); - TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, - &refBlackWhite); - - /* Do some validation to avoid later issues. Detect NaN for now */ - /* and also if lumaGreen is zero since we divide by it later */ - if( luma[0] != luma[0] || - luma[1] != luma[1] || - luma[1] == 0.0 || - luma[2] != luma[2] ) - { - TIFFErrorExtR(img->tif, module, - "Invalid values for YCbCrCoefficients tag"); - return (0); - } +static int initYCbCrConversion(TIFFRGBAImage *img) +{ + static const char module[] = "initYCbCrConversion"; - if( !isInRefBlackWhiteRange(refBlackWhite[0]) || - !isInRefBlackWhiteRange(refBlackWhite[1]) || - !isInRefBlackWhiteRange(refBlackWhite[2]) || - !isInRefBlackWhiteRange(refBlackWhite[3]) || - !isInRefBlackWhiteRange(refBlackWhite[4]) || - !isInRefBlackWhiteRange(refBlackWhite[5]) ) + float *luma, *refBlackWhite; + + if (img->ycbcr == NULL) + { + img->ycbcr = (TIFFYCbCrToRGB *)_TIFFmallocExt( + img->tif, TIFFroundup_32(sizeof(TIFFYCbCrToRGB), sizeof(long)) + + 4 * 256 * sizeof(TIFFRGBValue) + + 2 * 256 * sizeof(int) + 3 * 256 * sizeof(int32_t)); + if (img->ycbcr == NULL) { TIFFErrorExtR(img->tif, module, - "Invalid values for ReferenceBlackWhite tag"); + "No space for YCbCr->RGB conversion state"); return (0); } + } + + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); + TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, + &refBlackWhite); + + /* Do some validation to avoid later issues. Detect NaN for now */ + /* and also if lumaGreen is zero since we divide by it later */ + if (luma[0] != luma[0] || luma[1] != luma[1] || luma[1] == 0.0 || + luma[2] != luma[2]) + { + TIFFErrorExtR(img->tif, module, + "Invalid values for YCbCrCoefficients tag"); + return (0); + } + + if (!isInRefBlackWhiteRange(refBlackWhite[0]) || + !isInRefBlackWhiteRange(refBlackWhite[1]) || + !isInRefBlackWhiteRange(refBlackWhite[2]) || + !isInRefBlackWhiteRange(refBlackWhite[3]) || + !isInRefBlackWhiteRange(refBlackWhite[4]) || + !isInRefBlackWhiteRange(refBlackWhite[5])) + { + TIFFErrorExtR(img->tif, module, + "Invalid values for ReferenceBlackWhite tag"); + return (0); + } - if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) - return(0); - return (1); + if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) + return (0); + return (1); } -static tileContigRoutine -initCIELabConversion(TIFFRGBAImage* img) +static tileContigRoutine initCIELabConversion(TIFFRGBAImage *img) { - static const char module[] = "initCIELabConversion"; + static const char module[] = "initCIELabConversion"; + + float *whitePoint; + float refWhite[3]; - float *whitePoint; - float refWhite[3]; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); + if (whitePoint[1] == 0.0f) + { + TIFFErrorExtR(img->tif, module, "Invalid value for WhitePoint tag."); + return NULL; + } - TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); - if (whitePoint[1] == 0.0f ) { - TIFFErrorExtR(img->tif, module, - "Invalid value for WhitePoint tag."); - return NULL; + if (!img->cielab) + { + img->cielab = (TIFFCIELabToRGB *)_TIFFmallocExt( + img->tif, sizeof(TIFFCIELabToRGB)); + if (!img->cielab) + { + TIFFErrorExtR(img->tif, module, + "No space for CIE L*a*b*->RGB conversion state."); + return NULL; } + } + + refWhite[1] = 100.0F; + refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; + refWhite[2] = + (1.0F - whitePoint[0] - whitePoint[1]) / whitePoint[1] * refWhite[1]; + if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) + { + TIFFErrorExtR(img->tif, module, + "Failed to initialize CIE L*a*b*->RGB conversion state."); + _TIFFfreeExt(img->tif, img->cielab); + return NULL; + } - if (!img->cielab) { - img->cielab = (TIFFCIELabToRGB *) - _TIFFmallocExt(img->tif, sizeof(TIFFCIELabToRGB)); - if (!img->cielab) { - TIFFErrorExtR(img->tif, module, - "No space for CIE L*a*b*->RGB conversion state."); - return NULL; - } - } - - refWhite[1] = 100.0F; - refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; - refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1]) - / whitePoint[1] * refWhite[1]; - if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) { - TIFFErrorExtR(img->tif, module, - "Failed to initialize CIE L*a*b*->RGB conversion state."); - _TIFFfreeExt(img->tif, img->cielab); - return NULL; - } - - if (img->bitspersample == 8) - return putcontig8bitCIELab8; - else if (img->bitspersample == 16) - return putcontig8bitCIELab16; - return NULL; + if (img->bitspersample == 8) + return putcontig8bitCIELab8; + else if (img->bitspersample == 16) + return putcontig8bitCIELab16; + return NULL; } /* @@ -2365,56 +2659,62 @@ initCIELabConversion(TIFFRGBAImage* img) * pixel values simply by indexing into the table with one * number. */ -static int -makebwmap(TIFFRGBAImage* img) +static int makebwmap(TIFFRGBAImage *img) { - TIFFRGBValue* Map = img->Map; + TIFFRGBValue *Map = img->Map; int bitspersample = img->bitspersample; int nsamples = 8 / bitspersample; int i; - uint32_t* p; + uint32_t *p; - if( nsamples == 0 ) + if (nsamples == 0) nsamples = 1; - img->BWmap = (uint32_t**) _TIFFmallocExt(img->tif, - 256*sizeof (uint32_t *) + (256 * nsamples * sizeof(uint32_t))); - if (img->BWmap == NULL) { - TIFFErrorExtR(img->tif, TIFFFileName(img->tif), "No space for B&W mapping table"); - return (0); - } - p = (uint32_t*)(img->BWmap + 256); - for (i = 0; i < 256; i++) { - TIFFRGBValue c; - img->BWmap[i] = p; - switch (bitspersample) { -#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c); - case 1: - GREY(i>>7); - GREY((i>>6)&1); - GREY((i>>5)&1); - GREY((i>>4)&1); - GREY((i>>3)&1); - GREY((i>>2)&1); - GREY((i>>1)&1); - GREY(i&1); - break; - case 2: - GREY(i>>6); - GREY((i>>4)&3); - GREY((i>>2)&3); - GREY(i&3); - break; - case 4: - GREY(i>>4); - GREY(i&0xf); - break; - case 8: - case 16: - GREY(i); - break; - } -#undef GREY + img->BWmap = (uint32_t **)_TIFFmallocExt( + img->tif, + 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t))); + if (img->BWmap == NULL) + { + TIFFErrorExtR(img->tif, TIFFFileName(img->tif), + "No space for B&W mapping table"); + return (0); + } + p = (uint32_t *)(img->BWmap + 256); + for (i = 0; i < 256; i++) + { + TIFFRGBValue c; + img->BWmap[i] = p; + switch (bitspersample) + { +#define GREY(x) \ + c = Map[x]; \ + *p++ = PACK(c, c, c); + case 1: + GREY(i >> 7); + GREY((i >> 6) & 1); + GREY((i >> 5) & 1); + GREY((i >> 4) & 1); + GREY((i >> 3) & 1); + GREY((i >> 2) & 1); + GREY((i >> 1) & 1); + GREY(i & 1); + break; + case 2: + GREY(i >> 6); + GREY((i >> 4) & 3); + GREY((i >> 2) & 3); + GREY(i & 3); + break; + case 4: + GREY(i >> 4); + GREY(i & 0xf); + break; + case 8: + case 16: + GREY(i); + break; + } +#undef GREY } return (1); } @@ -2423,75 +2723,79 @@ makebwmap(TIFFRGBAImage* img) * Construct a mapping table to convert from the range * of the data samples to [0,255] --for display. This * process also handles inverting B&W images when needed. - */ -static int -setupMap(TIFFRGBAImage* img) + */ +static int setupMap(TIFFRGBAImage *img) { int32_t x, range; range = (int32_t)((1L << img->bitspersample) - 1); - + /* treat 16 bit the same as eight bit */ - if( img->bitspersample == 16 ) - range = (int32_t) 255; - - img->Map = (TIFFRGBValue*) _TIFFmallocExt(img->tif, (range+1) * sizeof (TIFFRGBValue)); - if (img->Map == NULL) { - TIFFErrorExtR(img->tif, TIFFFileName(img->tif), - "No space for photometric conversion table"); - return (0); - } - if (img->photometric == PHOTOMETRIC_MINISWHITE) { - for (x = 0; x <= range; x++) - img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range); - } else { - for (x = 0; x <= range; x++) - img->Map[x] = (TIFFRGBValue) ((x * 255) / range); + if (img->bitspersample == 16) + range = (int32_t)255; + + img->Map = (TIFFRGBValue *)_TIFFmallocExt( + img->tif, (range + 1) * sizeof(TIFFRGBValue)); + if (img->Map == NULL) + { + TIFFErrorExtR(img->tif, TIFFFileName(img->tif), + "No space for photometric conversion table"); + return (0); + } + if (img->photometric == PHOTOMETRIC_MINISWHITE) + { + for (x = 0; x <= range; x++) + img->Map[x] = (TIFFRGBValue)(((range - x) * 255) / range); + } + else + { + for (x = 0; x <= range; x++) + img->Map[x] = (TIFFRGBValue)((x * 255) / range); } if (img->bitspersample <= 16 && - (img->photometric == PHOTOMETRIC_MINISBLACK || - img->photometric == PHOTOMETRIC_MINISWHITE)) { - /* - * Use photometric mapping table to construct - * unpacking tables for samples <= 8 bits. - */ - if (!makebwmap(img)) - return (0); - /* no longer need Map, free it */ - _TIFFfreeExt(img->tif, img->Map); - img->Map = NULL; + (img->photometric == PHOTOMETRIC_MINISBLACK || + img->photometric == PHOTOMETRIC_MINISWHITE)) + { + /* + * Use photometric mapping table to construct + * unpacking tables for samples <= 8 bits. + */ + if (!makebwmap(img)) + return (0); + /* no longer need Map, free it */ + _TIFFfreeExt(img->tif, img->Map); + img->Map = NULL; } return (1); } -static int -checkcmap(TIFFRGBAImage* img) +static int checkcmap(TIFFRGBAImage *img) { - uint16_t* r = img->redcmap; - uint16_t* g = img->greencmap; - uint16_t* b = img->bluecmap; - long n = 1L<<img->bitspersample; + uint16_t *r = img->redcmap; + uint16_t *g = img->greencmap; + uint16_t *b = img->bluecmap; + long n = 1L << img->bitspersample; while (n-- > 0) - if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) - return (16); + if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) + return (16); return (8); } -static void -cvtcmap(TIFFRGBAImage* img) +static void cvtcmap(TIFFRGBAImage *img) { - uint16_t* r = img->redcmap; - uint16_t* g = img->greencmap; - uint16_t* b = img->bluecmap; + uint16_t *r = img->redcmap; + uint16_t *g = img->greencmap; + uint16_t *b = img->bluecmap; long i; - for (i = (1L<<img->bitspersample)-1; i >= 0; i--) { -#define CVT(x) ((uint16_t)((x)>>8)) - r[i] = CVT(r[i]); - g[i] = CVT(g[i]); - b[i] = CVT(b[i]); -#undef CVT + for (i = (1L << img->bitspersample) - 1; i >= 0; i--) + { +#define CVT(x) ((uint16_t)((x) >> 8)) + r[i] = CVT(r[i]); + g[i] = CVT(g[i]); + b[i] = CVT(b[i]); +#undef CVT } } @@ -2502,93 +2806,100 @@ cvtcmap(TIFFRGBAImage* img) * pixel values simply by indexing into the table with one * number. */ -static int -makecmap(TIFFRGBAImage* img) +static int makecmap(TIFFRGBAImage *img) { int bitspersample = img->bitspersample; int nsamples = 8 / bitspersample; - uint16_t* r = img->redcmap; - uint16_t* g = img->greencmap; - uint16_t* b = img->bluecmap; + uint16_t *r = img->redcmap; + uint16_t *g = img->greencmap; + uint16_t *b = img->bluecmap; uint32_t *p; int i; - img->PALmap = (uint32_t**) _TIFFmallocExt(img->tif, - 256*sizeof (uint32_t *) + (256 * nsamples * sizeof(uint32_t))); - if (img->PALmap == NULL) { - TIFFErrorExtR(img->tif, TIFFFileName(img->tif), "No space for Palette mapping table"); - return (0); - } - p = (uint32_t*)(img->PALmap + 256); - for (i = 0; i < 256; i++) { - TIFFRGBValue c; - img->PALmap[i] = p; -#define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff); - switch (bitspersample) { - case 1: - CMAP(i>>7); - CMAP((i>>6)&1); - CMAP((i>>5)&1); - CMAP((i>>4)&1); - CMAP((i>>3)&1); - CMAP((i>>2)&1); - CMAP((i>>1)&1); - CMAP(i&1); - break; - case 2: - CMAP(i>>6); - CMAP((i>>4)&3); - CMAP((i>>2)&3); - CMAP(i&3); - break; - case 4: - CMAP(i>>4); - CMAP(i&0xf); - break; - case 8: - CMAP(i); - break; - } + img->PALmap = (uint32_t **)_TIFFmallocExt( + img->tif, + 256 * sizeof(uint32_t *) + (256 * nsamples * sizeof(uint32_t))); + if (img->PALmap == NULL) + { + TIFFErrorExtR(img->tif, TIFFFileName(img->tif), + "No space for Palette mapping table"); + return (0); + } + p = (uint32_t *)(img->PALmap + 256); + for (i = 0; i < 256; i++) + { + TIFFRGBValue c; + img->PALmap[i] = p; +#define CMAP(x) \ + c = (TIFFRGBValue)x; \ + *p++ = PACK(r[c] & 0xff, g[c] & 0xff, b[c] & 0xff); + switch (bitspersample) + { + case 1: + CMAP(i >> 7); + CMAP((i >> 6) & 1); + CMAP((i >> 5) & 1); + CMAP((i >> 4) & 1); + CMAP((i >> 3) & 1); + CMAP((i >> 2) & 1); + CMAP((i >> 1) & 1); + CMAP(i & 1); + break; + case 2: + CMAP(i >> 6); + CMAP((i >> 4) & 3); + CMAP((i >> 2) & 3); + CMAP(i & 3); + break; + case 4: + CMAP(i >> 4); + CMAP(i & 0xf); + break; + case 8: + CMAP(i); + break; + } #undef CMAP } return (1); } -/* +/* * Construct any mapping table used * by the associated put routine. */ -static int -buildMap(TIFFRGBAImage* img) -{ - switch (img->photometric) { - case PHOTOMETRIC_RGB: - case PHOTOMETRIC_YCBCR: - case PHOTOMETRIC_SEPARATED: - if (img->bitspersample == 8) - break; - /* fall through... */ - case PHOTOMETRIC_MINISBLACK: - case PHOTOMETRIC_MINISWHITE: - if (!setupMap(img)) - return (0); - break; - case PHOTOMETRIC_PALETTE: - /* - * Convert 16-bit colormap to 8-bit (unless it looks - * like an old-style 8-bit colormap). - */ - if (checkcmap(img) == 16) - cvtcmap(img); - else - TIFFWarningExtR(img->tif, TIFFFileName(img->tif), "Assuming 8-bit colormap"); - /* - * Use mapping table and colormap to construct - * unpacking tables for samples < 8 bits. - */ - if (img->bitspersample <= 8 && !makecmap(img)) - return (0); - break; +static int buildMap(TIFFRGBAImage *img) +{ + switch (img->photometric) + { + case PHOTOMETRIC_RGB: + case PHOTOMETRIC_YCBCR: + case PHOTOMETRIC_SEPARATED: + if (img->bitspersample == 8) + break; + /* fall through... */ + case PHOTOMETRIC_MINISBLACK: + case PHOTOMETRIC_MINISWHITE: + if (!setupMap(img)) + return (0); + break; + case PHOTOMETRIC_PALETTE: + /* + * Convert 16-bit colormap to 8-bit (unless it looks + * like an old-style 8-bit colormap). + */ + if (checkcmap(img) == 16) + cvtcmap(img); + else + TIFFWarningExtR(img->tif, TIFFFileName(img->tif), + "Assuming 8-bit colormap"); + /* + * Use mapping table and colormap to construct + * unpacking tables for samples < 8 bits. + */ + if (img->bitspersample <= 8 && !makecmap(img)) + return (0); + break; } return (1); } @@ -2596,153 +2907,162 @@ buildMap(TIFFRGBAImage* img) /* * Select the appropriate conversion routine for packed data. */ -static int -PickContigCase(TIFFRGBAImage* img) -{ - img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig; - img->put.contig = NULL; - switch (img->photometric) { - case PHOTOMETRIC_RGB: - switch (img->bitspersample) { - case 8: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA && - img->samplesperpixel >= 4) - img->put.contig = putRGBAAcontig8bittile; - else if (img->alpha == EXTRASAMPLE_UNASSALPHA && - img->samplesperpixel >= 4) - { - if (BuildMapUaToAa(img)) - img->put.contig = putRGBUAcontig8bittile; - } - else if( img->samplesperpixel >= 3 ) - img->put.contig = putRGBcontig8bittile; - break; - case 16: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA && - img->samplesperpixel >=4 ) - { - if (BuildMapBitdepth16To8(img)) - img->put.contig = putRGBAAcontig16bittile; - } - else if (img->alpha == EXTRASAMPLE_UNASSALPHA && - img->samplesperpixel >=4 ) - { - if (BuildMapBitdepth16To8(img) && - BuildMapUaToAa(img)) - img->put.contig = putRGBUAcontig16bittile; - } - else if( img->samplesperpixel >=3 ) - { - if (BuildMapBitdepth16To8(img)) - img->put.contig = putRGBcontig16bittile; - } - break; - } - break; - case PHOTOMETRIC_SEPARATED: - if (img->samplesperpixel >=4 && buildMap(img)) { - if (img->bitspersample == 8) { - if (!img->Map) - img->put.contig = putRGBcontig8bitCMYKtile; - else - img->put.contig = putRGBcontig8bitCMYKMaptile; - } - } - break; - case PHOTOMETRIC_PALETTE: - if (buildMap(img)) { - switch (img->bitspersample) { - case 8: - img->put.contig = put8bitcmaptile; - break; - case 4: - img->put.contig = put4bitcmaptile; - break; - case 2: - img->put.contig = put2bitcmaptile; - break; - case 1: - img->put.contig = put1bitcmaptile; - break; - } - } - break; - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - if (buildMap(img)) { - switch (img->bitspersample) { - case 16: - img->put.contig = put16bitbwtile; - break; - case 8: - if (img->alpha && img->samplesperpixel == 2) - img->put.contig = putagreytile; - else - img->put.contig = putgreytile; - break; - case 4: - img->put.contig = put4bitbwtile; - break; - case 2: - img->put.contig = put2bitbwtile; - break; - case 1: - img->put.contig = put1bitbwtile; - break; - } - } - break; - case PHOTOMETRIC_YCBCR: - if ((img->bitspersample==8) && (img->samplesperpixel==3)) - { - if (initYCbCrConversion(img)!=0) - { - /* - * The 6.0 spec says that subsampling must be - * one of 1, 2, or 4, and that vertical subsampling - * must always be <= horizontal subsampling; so - * there are only a few possibilities and we just - * enumerate the cases. - * Joris: added support for the [1,2] case, nonetheless, to accommodate - * some OJPEG files - */ - uint16_t SubsamplingHor; - uint16_t SubsamplingVer; - TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer); - switch ((SubsamplingHor<<4)|SubsamplingVer) { - case 0x44: - img->put.contig = putcontig8bitYCbCr44tile; - break; - case 0x42: - img->put.contig = putcontig8bitYCbCr42tile; - break; - case 0x41: - img->put.contig = putcontig8bitYCbCr41tile; - break; - case 0x22: - img->put.contig = putcontig8bitYCbCr22tile; - break; - case 0x21: - img->put.contig = putcontig8bitYCbCr21tile; - break; - case 0x12: - img->put.contig = putcontig8bitYCbCr12tile; - break; - case 0x11: - img->put.contig = putcontig8bitYCbCr11tile; - break; - } - } - } - break; - case PHOTOMETRIC_CIELAB: - if (img->samplesperpixel == 3 && buildMap(img)) { - if (img->bitspersample == 8 || img->bitspersample == 16) - img->put.contig = initCIELabConversion(img); - break; - } - } - return ((img->get!=NULL) && (img->put.contig!=NULL)); +static int PickContigCase(TIFFRGBAImage *img) +{ + img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig; + img->put.contig = NULL; + switch (img->photometric) + { + case PHOTOMETRIC_RGB: + switch (img->bitspersample) + { + case 8: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA && + img->samplesperpixel >= 4) + img->put.contig = putRGBAAcontig8bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA && + img->samplesperpixel >= 4) + { + if (BuildMapUaToAa(img)) + img->put.contig = putRGBUAcontig8bittile; + } + else if (img->samplesperpixel >= 3) + img->put.contig = putRGBcontig8bittile; + break; + case 16: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA && + img->samplesperpixel >= 4) + { + if (BuildMapBitdepth16To8(img)) + img->put.contig = putRGBAAcontig16bittile; + } + else if (img->alpha == EXTRASAMPLE_UNASSALPHA && + img->samplesperpixel >= 4) + { + if (BuildMapBitdepth16To8(img) && BuildMapUaToAa(img)) + img->put.contig = putRGBUAcontig16bittile; + } + else if (img->samplesperpixel >= 3) + { + if (BuildMapBitdepth16To8(img)) + img->put.contig = putRGBcontig16bittile; + } + break; + } + break; + case PHOTOMETRIC_SEPARATED: + if (img->samplesperpixel >= 4 && buildMap(img)) + { + if (img->bitspersample == 8) + { + if (!img->Map) + img->put.contig = putRGBcontig8bitCMYKtile; + else + img->put.contig = putRGBcontig8bitCMYKMaptile; + } + } + break; + case PHOTOMETRIC_PALETTE: + if (buildMap(img)) + { + switch (img->bitspersample) + { + case 8: + img->put.contig = put8bitcmaptile; + break; + case 4: + img->put.contig = put4bitcmaptile; + break; + case 2: + img->put.contig = put2bitcmaptile; + break; + case 1: + img->put.contig = put1bitcmaptile; + break; + } + } + break; + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + if (buildMap(img)) + { + switch (img->bitspersample) + { + case 16: + img->put.contig = put16bitbwtile; + break; + case 8: + if (img->alpha && img->samplesperpixel == 2) + img->put.contig = putagreytile; + else + img->put.contig = putgreytile; + break; + case 4: + img->put.contig = put4bitbwtile; + break; + case 2: + img->put.contig = put2bitbwtile; + break; + case 1: + img->put.contig = put1bitbwtile; + break; + } + } + break; + case PHOTOMETRIC_YCBCR: + if ((img->bitspersample == 8) && (img->samplesperpixel == 3)) + { + if (initYCbCrConversion(img) != 0) + { + /* + * The 6.0 spec says that subsampling must be + * one of 1, 2, or 4, and that vertical subsampling + * must always be <= horizontal subsampling; so + * there are only a few possibilities and we just + * enumerate the cases. + * Joris: added support for the [1,2] case, nonetheless, to + * accommodate some OJPEG files + */ + uint16_t SubsamplingHor; + uint16_t SubsamplingVer; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, + &SubsamplingHor, &SubsamplingVer); + switch ((SubsamplingHor << 4) | SubsamplingVer) + { + case 0x44: + img->put.contig = putcontig8bitYCbCr44tile; + break; + case 0x42: + img->put.contig = putcontig8bitYCbCr42tile; + break; + case 0x41: + img->put.contig = putcontig8bitYCbCr41tile; + break; + case 0x22: + img->put.contig = putcontig8bitYCbCr22tile; + break; + case 0x21: + img->put.contig = putcontig8bitYCbCr21tile; + break; + case 0x12: + img->put.contig = putcontig8bitYCbCr12tile; + break; + case 0x11: + img->put.contig = putcontig8bitYCbCr11tile; + break; + } + } + } + break; + case PHOTOMETRIC_CIELAB: + if (img->samplesperpixel == 3 && buildMap(img)) + { + if (img->bitspersample == 8 || img->bitspersample == 16) + img->put.contig = initCIELabConversion(img); + break; + } + } + return ((img->get != NULL) && (img->put.contig != NULL)); } /* @@ -2751,116 +3071,117 @@ PickContigCase(TIFFRGBAImage* img) * NB: we assume that unpacked single channel data is directed * to the "packed routines. */ -static int -PickSeparateCase(TIFFRGBAImage* img) -{ - img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; - img->put.separate = NULL; - switch (img->photometric) { - case PHOTOMETRIC_MINISWHITE: - case PHOTOMETRIC_MINISBLACK: - /* greyscale images processed pretty much as RGB by gtTileSeparate */ - case PHOTOMETRIC_RGB: - switch (img->bitspersample) { - case 8: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA) - img->put.separate = putRGBAAseparate8bittile; - else if (img->alpha == EXTRASAMPLE_UNASSALPHA) - { - if (BuildMapUaToAa(img)) - img->put.separate = putRGBUAseparate8bittile; - } - else - img->put.separate = putRGBseparate8bittile; - break; - case 16: - if (img->alpha == EXTRASAMPLE_ASSOCALPHA) - { - if (BuildMapBitdepth16To8(img)) - img->put.separate = putRGBAAseparate16bittile; - } - else if (img->alpha == EXTRASAMPLE_UNASSALPHA) - { - if (BuildMapBitdepth16To8(img) && - BuildMapUaToAa(img)) - img->put.separate = putRGBUAseparate16bittile; - } - else - { - if (BuildMapBitdepth16To8(img)) - img->put.separate = putRGBseparate16bittile; - } - break; - } - break; - case PHOTOMETRIC_SEPARATED: - if (img->bitspersample == 8 && img->samplesperpixel == 4) - { - img->alpha = 1; // Not alpha, but seems like the only way to get 4th band - img->put.separate = putCMYKseparate8bittile; - } - break; - case PHOTOMETRIC_YCBCR: - if ((img->bitspersample==8) && (img->samplesperpixel==3)) - { - if (initYCbCrConversion(img)!=0) - { - uint16_t hs, vs; - TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); - switch ((hs<<4)|vs) { - case 0x11: - img->put.separate = putseparate8bitYCbCr11tile; - break; - /* TODO: add other cases here */ - } - } - } - break; - } - return ((img->get!=NULL) && (img->put.separate!=NULL)); -} - -static int -BuildMapUaToAa(TIFFRGBAImage* img) -{ - static const char module[]="BuildMapUaToAa"; - uint8_t* m; - uint16_t na,nv; - assert(img->UaToAa==NULL); - img->UaToAa=_TIFFmallocExt(img->tif, 65536); - if (img->UaToAa==NULL) - { - TIFFErrorExtR(img->tif,module,"Out of memory"); - return(0); - } - m=img->UaToAa; - for (na=0; na<256; na++) - { - for (nv=0; nv<256; nv++) - *m++=(uint8_t)((nv * na + 127) / 255); - } - return(1); -} - -static int -BuildMapBitdepth16To8(TIFFRGBAImage* img) -{ - static const char module[]="BuildMapBitdepth16To8"; - uint8_t* m; - uint32_t n; - assert(img->Bitdepth16To8==NULL); - img->Bitdepth16To8=_TIFFmallocExt(img->tif, 65536); - if (img->Bitdepth16To8==NULL) - { - TIFFErrorExtR(img->tif,module,"Out of memory"); - return(0); - } - m=img->Bitdepth16To8; - for (n=0; n<65536; n++) - *m++=(uint8_t)((n + 128) / 257); - return(1); +static int PickSeparateCase(TIFFRGBAImage *img) +{ + img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate; + img->put.separate = NULL; + switch (img->photometric) + { + case PHOTOMETRIC_MINISWHITE: + case PHOTOMETRIC_MINISBLACK: + /* greyscale images processed pretty much as RGB by gtTileSeparate + */ + case PHOTOMETRIC_RGB: + switch (img->bitspersample) + { + case 8: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + img->put.separate = putRGBAAseparate8bittile; + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + { + if (BuildMapUaToAa(img)) + img->put.separate = putRGBUAseparate8bittile; + } + else + img->put.separate = putRGBseparate8bittile; + break; + case 16: + if (img->alpha == EXTRASAMPLE_ASSOCALPHA) + { + if (BuildMapBitdepth16To8(img)) + img->put.separate = putRGBAAseparate16bittile; + } + else if (img->alpha == EXTRASAMPLE_UNASSALPHA) + { + if (BuildMapBitdepth16To8(img) && BuildMapUaToAa(img)) + img->put.separate = putRGBUAseparate16bittile; + } + else + { + if (BuildMapBitdepth16To8(img)) + img->put.separate = putRGBseparate16bittile; + } + break; + } + break; + case PHOTOMETRIC_SEPARATED: + if (img->bitspersample == 8 && img->samplesperpixel == 4) + { + img->alpha = + 1; // Not alpha, but seems like the only way to get 4th band + img->put.separate = putCMYKseparate8bittile; + } + break; + case PHOTOMETRIC_YCBCR: + if ((img->bitspersample == 8) && (img->samplesperpixel == 3)) + { + if (initYCbCrConversion(img) != 0) + { + uint16_t hs, vs; + TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, + &hs, &vs); + switch ((hs << 4) | vs) + { + case 0x11: + img->put.separate = putseparate8bitYCbCr11tile; + break; + /* TODO: add other cases here */ + } + } + } + break; + } + return ((img->get != NULL) && (img->put.separate != NULL)); +} + +static int BuildMapUaToAa(TIFFRGBAImage *img) +{ + static const char module[] = "BuildMapUaToAa"; + uint8_t *m; + uint16_t na, nv; + assert(img->UaToAa == NULL); + img->UaToAa = _TIFFmallocExt(img->tif, 65536); + if (img->UaToAa == NULL) + { + TIFFErrorExtR(img->tif, module, "Out of memory"); + return (0); + } + m = img->UaToAa; + for (na = 0; na < 256; na++) + { + for (nv = 0; nv < 256; nv++) + *m++ = (uint8_t)((nv * na + 127) / 255); + } + return (1); } +static int BuildMapBitdepth16To8(TIFFRGBAImage *img) +{ + static const char module[] = "BuildMapBitdepth16To8"; + uint8_t *m; + uint32_t n; + assert(img->Bitdepth16To8 == NULL); + img->Bitdepth16To8 = _TIFFmallocExt(img->tif, 65536); + if (img->Bitdepth16To8 == NULL) + { + TIFFErrorExtR(img->tif, module, "Out of memory"); + return (0); + } + m = img->Bitdepth16To8; + for (n = 0; n < 65536; n++) + *m++ = (uint8_t)((n + 128) / 257); + return (1); +} /* * Read a whole strip off data from the file, and convert to RGBA form. @@ -2869,56 +3190,59 @@ BuildMapBitdepth16To8(TIFFRGBAImage* img) * organized in bottom to top form. */ - -int -TIFFReadRGBAStrip(TIFF* tif, uint32_t row, uint32_t * raster ) +int TIFFReadRGBAStrip(TIFF *tif, uint32_t row, uint32_t *raster) { - return TIFFReadRGBAStripExt(tif, row, raster, 0 ); + return TIFFReadRGBAStripExt(tif, row, raster, 0); } -int -TIFFReadRGBAStripExt(TIFF* tif, uint32_t row, uint32_t * raster, int stop_on_error) +int TIFFReadRGBAStripExt(TIFF *tif, uint32_t row, uint32_t *raster, + int stop_on_error) { - char emsg[EMSG_BUF_SIZE] = ""; + char emsg[EMSG_BUF_SIZE] = ""; TIFFRGBAImage img; - int ok; - uint32_t rowsperstrip, rows_to_read; + int ok; + uint32_t rowsperstrip, rows_to_read; - if( TIFFIsTiled( tif ) ) + if (TIFFIsTiled(tif)) { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Can't use TIFFReadRGBAStrip() with tiled file."); - return (0); + TIFFErrorExtR(tif, TIFFFileName(tif), + "Can't use TIFFReadRGBAStrip() with tiled file."); + return (0); } - + TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); - if( (row % rowsperstrip) != 0 ) + if ((row % rowsperstrip) != 0) { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Row passed to TIFFReadRGBAStrip() must be first in a strip."); - return (0); + TIFFErrorExtR( + tif, TIFFFileName(tif), + "Row passed to TIFFReadRGBAStrip() must be first in a strip."); + return (0); } - if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) { + if (TIFFRGBAImageOK(tif, emsg) && + TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) + { img.row_offset = row; img.col_offset = 0; - if( row + rowsperstrip > img.height ) + if (row + rowsperstrip > img.height) rows_to_read = img.height - row; else rows_to_read = rowsperstrip; - - ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read ); - - TIFFRGBAImageEnd(&img); - } else { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); - ok = 0; - } - + + ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read); + + TIFFRGBAImageEnd(&img); + } + else + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); + ok = 0; + } + return (ok); } @@ -2928,54 +3252,53 @@ TIFFReadRGBAStripExt(TIFF* tif, uint32_t row, uint32_t * raster, int stop_on_err * and may include zeroed areas if the tile extends off the image. */ -int -TIFFReadRGBATile(TIFF* tif, uint32_t col, uint32_t row, uint32_t * raster) +int TIFFReadRGBATile(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster) { - return TIFFReadRGBATileExt(tif, col, row, raster, 0 ); + return TIFFReadRGBATileExt(tif, col, row, raster, 0); } - -int -TIFFReadRGBATileExt(TIFF* tif, uint32_t col, uint32_t row, uint32_t * raster, int stop_on_error ) +int TIFFReadRGBATileExt(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster, + int stop_on_error) { - char emsg[EMSG_BUF_SIZE] = ""; + char emsg[EMSG_BUF_SIZE] = ""; TIFFRGBAImage img; - int ok; - uint32_t tile_xsize, tile_ysize; - uint32_t read_xsize, read_ysize; - uint32_t i_row; + int ok; + uint32_t tile_xsize, tile_ysize; + uint32_t read_xsize, read_ysize; + uint32_t i_row; /* * Verify that our request is legal - on a tile file, and on a * tile boundary. */ - - if( !TIFFIsTiled( tif ) ) + + if (!TIFFIsTiled(tif)) { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Can't use TIFFReadRGBATile() with striped file."); - return (0); + TIFFErrorExtR(tif, TIFFFileName(tif), + "Can't use TIFFReadRGBATile() with striped file."); + return (0); } - + TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize); TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize); - if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 ) + if ((col % tile_xsize) != 0 || (row % tile_ysize) != 0) { - TIFFErrorExtR(tif, TIFFFileName(tif), - "Row/col passed to TIFFReadRGBATile() must be top" - "left corner of a tile."); - return (0); + TIFFErrorExtR(tif, TIFFFileName(tif), + "Row/col passed to TIFFReadRGBATile() must be top" + "left corner of a tile."); + return (0); } /* * Setup the RGBA reader. */ - - if (!TIFFRGBAImageOK(tif, emsg) - || !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) { - TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); - return( 0 ); + + if (!TIFFRGBAImageOK(tif, emsg) || + !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "%s", emsg); + return (0); } /* @@ -2985,12 +3308,12 @@ TIFFReadRGBATileExt(TIFF* tif, uint32_t col, uint32_t row, uint32_t * raster, in * a full tile configuration afterwards. */ - if( row + tile_ysize > img.height ) + if (row + tile_ysize > img.height) read_ysize = img.height - row; else read_ysize = tile_ysize; - - if( col + tile_xsize > img.width ) + + if (col + tile_xsize > img.width) read_xsize = img.width - col; else read_xsize = tile_xsize; @@ -2998,12 +3321,12 @@ TIFFReadRGBATileExt(TIFF* tif, uint32_t col, uint32_t row, uint32_t * raster, in /* * Read the chunk of imagery. */ - + img.row_offset = row; img.col_offset = col; - ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize ); - + ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize); + TIFFRGBAImageEnd(&img); /* @@ -3011,23 +3334,26 @@ TIFFReadRGBATileExt(TIFF* tif, uint32_t col, uint32_t row, uint32_t * raster, in * shifting the data around as if a full tile of data is being returned. * * This is all the more complicated because the image is organized in - * bottom to top format. + * bottom to top format. */ - if( read_xsize == tile_xsize && read_ysize == tile_ysize ) - return( ok ); + if (read_xsize == tile_xsize && read_ysize == tile_ysize) + return (ok); - for( i_row = 0; i_row < read_ysize; i_row++ ) { - memmove( raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize, - raster + (size_t)(read_ysize - i_row - 1) * read_xsize, - read_xsize * sizeof(uint32_t) ); - _TIFFmemset( raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize+read_xsize, - 0, sizeof(uint32_t) * (tile_xsize - read_xsize) ); + for (i_row = 0; i_row < read_ysize; i_row++) + { + memmove(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize, + raster + (size_t)(read_ysize - i_row - 1) * read_xsize, + read_xsize * sizeof(uint32_t)); + _TIFFmemset(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize + + read_xsize, + 0, sizeof(uint32_t) * (tile_xsize - read_xsize)); } - for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) { - _TIFFmemset( raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize, - 0, sizeof(uint32_t) * tile_xsize ); + for (i_row = read_ysize; i_row < tile_ysize; i_row++) + { + _TIFFmemset(raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize, 0, + sizeof(uint32_t) * tile_xsize); } return (ok); diff --git a/libtiff/tif_jbig.c b/libtiff/tif_jbig.c index 4f3b09c7..7e455ad1 100644 --- a/libtiff/tif_jbig.c +++ b/libtiff/tif_jbig.c @@ -35,199 +35,197 @@ #ifdef JBIG_SUPPORT #include "jbig.h" -static int JBIGSetupDecode(TIFF* tif) +static int JBIGSetupDecode(TIFF *tif) { - if (TIFFNumberOfStrips(tif) != 1) - { - TIFFErrorExtR(tif, "JBIG", "Multistrip images not supported in decoder"); - return 0; - } - - return 1; + if (TIFFNumberOfStrips(tif) != 1) + { + TIFFErrorExtR(tif, "JBIG", + "Multistrip images not supported in decoder"); + return 0; + } + + return 1; } -static int JBIGDecode(TIFF* tif, uint8_t* buffer, tmsize_t size, uint16_t s) +static int JBIGDecode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s) { - struct jbg_dec_state decoder; - int decodeStatus = 0; - unsigned char* pImage = NULL; - unsigned long decodedSize; - (void) s; + struct jbg_dec_state decoder; + int decodeStatus = 0; + unsigned char *pImage = NULL; + unsigned long decodedSize; + (void)s; - if (isFillOrder(tif, tif->tif_dir.td_fillorder)) - { - TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc); - } + if (isFillOrder(tif, tif->tif_dir.td_fillorder)) + { + TIFFReverseBits(tif->tif_rawcp, tif->tif_rawcc); + } - jbg_dec_init(&decoder); + jbg_dec_init(&decoder); #if defined(HAVE_JBG_NEWLEN) - jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc); - /* - * I do not check the return status of jbg_newlen because even if this - * function fails it does not necessarily mean that decoding the image - * will fail. It is generally only needed for received fax images - * that do not contain the actual length of the image in the BIE - * header. I do not log when an error occurs because that will cause - * problems when converting JBIG encoded TIFF's to - * PostScript. As long as the actual image length is contained in the - * BIE header jbg_dec_in should succeed. - */ + jbg_newlen(tif->tif_rawcp, (size_t)tif->tif_rawcc); + /* + * I do not check the return status of jbg_newlen because even if this + * function fails it does not necessarily mean that decoding the image + * will fail. It is generally only needed for received fax images + * that do not contain the actual length of the image in the BIE + * header. I do not log when an error occurs because that will cause + * problems when converting JBIG encoded TIFF's to + * PostScript. As long as the actual image length is contained in the + * BIE header jbg_dec_in should succeed. + */ #endif /* HAVE_JBG_NEWLEN */ - decodeStatus = jbg_dec_in(&decoder, (unsigned char*)tif->tif_rawcp, - (size_t)tif->tif_rawcc, NULL); - if (JBG_EOK != decodeStatus) - { - /* - * XXX: JBG_EN constant was defined in pre-2.0 releases of the - * JBIG-KIT. Since the 2.0 the error reporting functions were - * changed. We will handle both cases here. - */ - TIFFErrorExtR(tif, - "JBIG", "Error (%d) decoding: %s", - decodeStatus, + decodeStatus = jbg_dec_in(&decoder, (unsigned char *)tif->tif_rawcp, + (size_t)tif->tif_rawcc, NULL); + if (JBG_EOK != decodeStatus) + { + /* + * XXX: JBG_EN constant was defined in pre-2.0 releases of the + * JBIG-KIT. Since the 2.0 the error reporting functions were + * changed. We will handle both cases here. + */ + TIFFErrorExtR(tif, "JBIG", "Error (%d) decoding: %s", decodeStatus, #if defined(JBG_EN) - jbg_strerror(decodeStatus, JBG_EN) + jbg_strerror(decodeStatus, JBG_EN) #else - jbg_strerror(decodeStatus) + jbg_strerror(decodeStatus) #endif - ); - jbg_dec_free(&decoder); - return 0; - } - - decodedSize = jbg_dec_getsize(&decoder); - if( (tmsize_t)decodedSize < size ) - { - TIFFWarningExtR(tif, "JBIG", - "Only decoded %lu bytes, whereas %"TIFF_SSIZE_FORMAT" requested", - decodedSize, size); - } - else if( (tmsize_t)decodedSize > size ) - { - TIFFErrorExtR(tif, "JBIG", - "Decoded %lu bytes, whereas %"TIFF_SSIZE_FORMAT" were requested", - decodedSize, size); - jbg_dec_free(&decoder); - return 0; - } - pImage = jbg_dec_getimage(&decoder, 0); - _TIFFmemcpy(buffer, pImage, decodedSize); - jbg_dec_free(&decoder); - - tif->tif_rawcp += tif->tif_rawcc; - tif->tif_rawcc = 0; - - return 1; + ); + jbg_dec_free(&decoder); + return 0; + } + + decodedSize = jbg_dec_getsize(&decoder); + if ((tmsize_t)decodedSize < size) + { + TIFFWarningExtR(tif, "JBIG", + "Only decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT + " requested", + decodedSize, size); + } + else if ((tmsize_t)decodedSize > size) + { + TIFFErrorExtR(tif, "JBIG", + "Decoded %lu bytes, whereas %" TIFF_SSIZE_FORMAT + " were requested", + decodedSize, size); + jbg_dec_free(&decoder); + return 0; + } + pImage = jbg_dec_getimage(&decoder, 0); + _TIFFmemcpy(buffer, pImage, decodedSize); + jbg_dec_free(&decoder); + + tif->tif_rawcp += tif->tif_rawcc; + tif->tif_rawcc = 0; + + return 1; } -static int JBIGSetupEncode(TIFF* tif) +static int JBIGSetupEncode(TIFF *tif) { - if (TIFFNumberOfStrips(tif) != 1) - { - TIFFErrorExtR(tif, "JBIG", "Multistrip images not supported in encoder"); - return 0; - } - - return 1; + if (TIFFNumberOfStrips(tif) != 1) + { + TIFFErrorExtR(tif, "JBIG", + "Multistrip images not supported in encoder"); + return 0; + } + + return 1; } -static int JBIGCopyEncodedData(TIFF* tif, unsigned char* pp, size_t cc, uint16_t s) +static int JBIGCopyEncodedData(TIFF *tif, unsigned char *pp, size_t cc, + uint16_t s) { - (void) s; - while (cc > 0) - { - tmsize_t n = (tmsize_t)cc; - - if (tif->tif_rawcc + n > tif->tif_rawdatasize) - { - n = tif->tif_rawdatasize - tif->tif_rawcc; - } - - assert(n > 0); - _TIFFmemcpy(tif->tif_rawcp, pp, n); - tif->tif_rawcp += n; - tif->tif_rawcc += n; - pp += n; - cc -= (size_t)n; - if (tif->tif_rawcc >= tif->tif_rawdatasize && - !TIFFFlushData1(tif)) - { - return (-1); - } - } - - return (1); + (void)s; + while (cc > 0) + { + tmsize_t n = (tmsize_t)cc; + + if (tif->tif_rawcc + n > tif->tif_rawdatasize) + { + n = tif->tif_rawdatasize - tif->tif_rawcc; + } + + assert(n > 0); + _TIFFmemcpy(tif->tif_rawcp, pp, n); + tif->tif_rawcp += n; + tif->tif_rawcc += n; + pp += n; + cc -= (size_t)n; + if (tif->tif_rawcc >= tif->tif_rawdatasize && !TIFFFlushData1(tif)) + { + return (-1); + } + } + + return (1); } -static void JBIGOutputBie(unsigned char* buffer, size_t len, void* userData) +static void JBIGOutputBie(unsigned char *buffer, size_t len, void *userData) { - TIFF* tif = (TIFF*)userData; + TIFF *tif = (TIFF *)userData; - if (isFillOrder(tif, tif->tif_dir.td_fillorder)) - { - TIFFReverseBits(buffer, (tmsize_t)len); - } + if (isFillOrder(tif, tif->tif_dir.td_fillorder)) + { + TIFFReverseBits(buffer, (tmsize_t)len); + } - JBIGCopyEncodedData(tif, buffer, len, 0); + JBIGCopyEncodedData(tif, buffer, len, 0); } -static int JBIGEncode(TIFF* tif, uint8_t* buffer, tmsize_t size, uint16_t s) +static int JBIGEncode(TIFF *tif, uint8_t *buffer, tmsize_t size, uint16_t s) { - TIFFDirectory* dir = &tif->tif_dir; - struct jbg_enc_state encoder; - - (void) size, (void) s; - - jbg_enc_init(&encoder, - dir->td_imagewidth, - dir->td_imagelength, - 1, - &buffer, - JBIGOutputBie, - tif); - /* - * jbg_enc_out does the "real" encoding. As data is encoded, - * JBIGOutputBie is called, which writes the data to the directory. - */ - jbg_enc_out(&encoder); - jbg_enc_free(&encoder); - - return 1; + TIFFDirectory *dir = &tif->tif_dir; + struct jbg_enc_state encoder; + + (void)size, (void)s; + + jbg_enc_init(&encoder, dir->td_imagewidth, dir->td_imagelength, 1, &buffer, + JBIGOutputBie, tif); + /* + * jbg_enc_out does the "real" encoding. As data is encoded, + * JBIGOutputBie is called, which writes the data to the directory. + */ + jbg_enc_out(&encoder); + jbg_enc_free(&encoder); + + return 1; } -int TIFFInitJBIG(TIFF* tif, int scheme) +int TIFFInitJBIG(TIFF *tif, int scheme) { - (void)scheme; - assert(scheme == COMPRESSION_JBIG); - - /* - * These flags are set so the JBIG Codec can control when to reverse - * bits and when not to and to allow the jbig decoder and bit reverser - * to write to memory when necessary. - */ - tif->tif_flags |= TIFF_NOBITREV; - tif->tif_flags &= ~TIFF_MAPPED; - /* We may have read from a previous IFD and thus set TIFF_BUFFERMMAP and - * cleared TIFF_MYBUFFER. It is necessary to restore them to their initial - * value to be consistent with the state of a non-memory mapped file. - */ - if (tif->tif_flags&TIFF_BUFFERMMAP) { - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - tif->tif_flags &= ~TIFF_BUFFERMMAP; - tif->tif_flags |= TIFF_MYBUFFER; - } - - /* Setup the function pointers for encode, decode, and cleanup. */ - tif->tif_setupdecode = JBIGSetupDecode; - tif->tif_decodestrip = JBIGDecode; - - tif->tif_setupencode = JBIGSetupEncode; - tif->tif_encodestrip = JBIGEncode; - - return 1; + (void)scheme; + assert(scheme == COMPRESSION_JBIG); + + /* + * These flags are set so the JBIG Codec can control when to reverse + * bits and when not to and to allow the jbig decoder and bit reverser + * to write to memory when necessary. + */ + tif->tif_flags |= TIFF_NOBITREV; + tif->tif_flags &= ~TIFF_MAPPED; + /* We may have read from a previous IFD and thus set TIFF_BUFFERMMAP and + * cleared TIFF_MYBUFFER. It is necessary to restore them to their initial + * value to be consistent with the state of a non-memory mapped file. + */ + if (tif->tif_flags & TIFF_BUFFERMMAP) + { + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + tif->tif_flags &= ~TIFF_BUFFERMMAP; + tif->tif_flags |= TIFF_MYBUFFER; + } + + /* Setup the function pointers for encode, decode, and cleanup. */ + tif->tif_setupdecode = JBIGSetupDecode; + tif->tif_decodestrip = JBIGDecode; + + tif->tif_setupencode = JBIGSetupEncode; + tif->tif_encodestrip = JBIGEncode; + + return 1; } #endif /* JBIG_SUPPORT */ diff --git a/libtiff/tif_jpeg.c b/libtiff/tif_jpeg.c index 97345b0e..250144f2 100644 --- a/libtiff/tif_jpeg.c +++ b/libtiff/tif_jpeg.c @@ -47,23 +47,24 @@ /* Settings that are independent of libjpeg ABI. Used when reinitializing the */ /* JPEGState from libjpegs 8 bit to libjpeg 12 bits, which have potentially */ /* different ABI */ -typedef struct { - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ - TIFFStripMethod defsparent; /* super-class method */ - TIFFTileMethod deftparent; /* super-class method */ - - /* pseudo-tag fields */ - void *jpegtables; /* JPEGTables tag value, or NULL */ - uint32_t jpegtables_length; /* number of bytes in same */ - int jpegquality; /* Compression quality level */ - int jpegcolormode; /* Auto RGB<=>YCbCr convert? */ - int jpegtablesmode; /* What to put in JPEGTables */ - - int ycbcrsampling_fetched; - int max_allowed_scan_number; - int has_warned_about_progressive_mode; +typedef struct +{ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ + TIFFStripMethod defsparent; /* super-class method */ + TIFFTileMethod deftparent; /* super-class method */ + + /* pseudo-tag fields */ + void *jpegtables; /* JPEGTables tag value, or NULL */ + uint32_t jpegtables_length; /* number of bytes in same */ + int jpegquality; /* Compression quality level */ + int jpegcolormode; /* Auto RGB<=>YCbCr convert? */ + int jpegtablesmode; /* What to put in JPEGTables */ + + int ycbcrsampling_fetched; + int max_allowed_scan_number; + int has_warned_about_progressive_mode; } JPEGOtherSettings; int TIFFFillStrip(TIFF *tif, uint32_t strip); @@ -129,29 +130,31 @@ typedef unsigned char boolean; */ #if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) -# define JPEG_DUAL_MODE_8_12 -/* Start by undefining BITS_IN_JSAMPLE which is always set to 8 in libjpeg-turbo >= 2.2 - * Cf https://github.com/libjpeg-turbo/libjpeg-turbo/commit/8b9bc4b9635a2a047fb23ebe70c9acd728d3f99b */ -# undef BITS_IN_JSAMPLE +#define JPEG_DUAL_MODE_8_12 +/* Start by undefining BITS_IN_JSAMPLE which is always set to 8 in libjpeg-turbo + * >= 2.2 Cf + * https://github.com/libjpeg-turbo/libjpeg-turbo/commit/8b9bc4b9635a2a047fb23ebe70c9acd728d3f99b + */ +#undef BITS_IN_JSAMPLE /* libjpeg-turbo >= 2.2 adds J12xxxx datatypes for the 12-bit mode. */ -# if defined(FROM_TIF_JPEG_12) -# define BITS_IN_JSAMPLE 12 -# define TIFF_JSAMPLE J12SAMPLE -# define TIFF_JSAMPARRAY J12SAMPARRAY -# define TIFF_JSAMPIMAGE J12SAMPIMAGE -# define TIFF_JSAMPROW J12SAMPROW -# else -# define BITS_IN_JSAMPLE 8 -# define TIFF_JSAMPLE JSAMPLE -# define TIFF_JSAMPARRAY JSAMPARRAY -# define TIFF_JSAMPIMAGE JSAMPIMAGE -# define TIFF_JSAMPROW JSAMPROW -# endif +#if defined(FROM_TIF_JPEG_12) +#define BITS_IN_JSAMPLE 12 +#define TIFF_JSAMPLE J12SAMPLE +#define TIFF_JSAMPARRAY J12SAMPARRAY +#define TIFF_JSAMPIMAGE J12SAMPIMAGE +#define TIFF_JSAMPROW J12SAMPROW #else -# define TIFF_JSAMPLE JSAMPLE -# define TIFF_JSAMPARRAY JSAMPARRAY -# define TIFF_JSAMPIMAGE JSAMPIMAGE -# define TIFF_JSAMPROW JSAMPROW +#define BITS_IN_JSAMPLE 8 +#define TIFF_JSAMPLE JSAMPLE +#define TIFF_JSAMPARRAY JSAMPARRAY +#define TIFF_JSAMPIMAGE JSAMPIMAGE +#define TIFF_JSAMPROW JSAMPROW +#endif +#else +#define TIFF_JSAMPLE JSAMPLE +#define TIFF_JSAMPARRAY JSAMPARRAY +#define TIFF_JSAMPIMAGE JSAMPIMAGE +#define TIFF_JSAMPROW JSAMPROW #endif #if defined(JPEG_LIB_MK1) @@ -196,36 +199,38 @@ typedef struct jpeg_error_mgr jpeg_error_mgr; * so we can safely cast JPEGState* -> jpeg_xxx_struct* * and vice versa! */ -typedef struct { - union { - struct jpeg_compress_struct c; - struct jpeg_decompress_struct d; - struct jpeg_common_struct comm; - } cinfo; /* NB: must be first */ - int cinfo_initialized; - - jpeg_error_mgr err; /* libjpeg error manager */ - JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ - - struct jpeg_progress_mgr progress; - /* - * The following two members could be a union, but - * they're small enough that it's not worth the effort. - */ - jpeg_destination_mgr dest; /* data dest for compression */ - jpeg_source_mgr src; /* data source for decompression */ - /* private state */ - TIFF *tif; /* back link needed by some code */ - uint16_t photometric; /* copy of PhotometricInterpretation */ - uint16_t h_sampling; /* luminance sampling factors */ - uint16_t v_sampling; - tmsize_t bytesperline; /* decompressed bytes per scanline */ - /* pointers to intermediate buffers when processing downsampled data */ - TIFF_JSAMPARRAY ds_buffer[MAX_COMPONENTS]; - int scancount; /* number of "scanlines" accumulated */ - int samplesperclump; - - JPEGOtherSettings otherSettings; +typedef struct +{ + union + { + struct jpeg_compress_struct c; + struct jpeg_decompress_struct d; + struct jpeg_common_struct comm; + } cinfo; /* NB: must be first */ + int cinfo_initialized; + + jpeg_error_mgr err; /* libjpeg error manager */ + JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */ + + struct jpeg_progress_mgr progress; + /* + * The following two members could be a union, but + * they're small enough that it's not worth the effort. + */ + jpeg_destination_mgr dest; /* data dest for compression */ + jpeg_source_mgr src; /* data source for decompression */ + /* private state */ + TIFF *tif; /* back link needed by some code */ + uint16_t photometric; /* copy of PhotometricInterpretation */ + uint16_t h_sampling; /* luminance sampling factors */ + uint16_t v_sampling; + tmsize_t bytesperline; /* decompressed bytes per scanline */ + /* pointers to intermediate buffers when processing downsampled data */ + TIFF_JSAMPARRAY ds_buffer[MAX_COMPONENTS]; + int scancount; /* number of "scanlines" accumulated */ + int samplesperclump; + + JPEGOtherSettings otherSettings; } JPEGState; #define JState(tif) ((JPEGState *)(tif)->tif_data) @@ -263,15 +268,16 @@ static const TIFFField jpegFields[] = { * IJG routines from jerror.c). These are used for both * compression and decompression. */ -static void TIFFjpeg_error_exit(j_common_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */ - char buffer[JMSG_LENGTH_MAX]; +static void TIFFjpeg_error_exit(j_common_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */ + char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo, buffer); - TIFFErrorExtR(sp->tif, "JPEGLib", "%s", - buffer); /* display the error message */ - jpeg_abort(cinfo); /* clean up libjpeg state */ - LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ + (*cinfo->err->format_message)(cinfo, buffer); + TIFFErrorExtR(sp->tif, "JPEGLib", "%s", + buffer); /* display the error message */ + jpeg_abort(cinfo); /* clean up libjpeg state */ + LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ } /* @@ -279,12 +285,12 @@ static void TIFFjpeg_error_exit(j_common_ptr cinfo) { * since error_exit does its own thing and trace_level * is never set > 0. */ -static void TIFFjpeg_output_message(j_common_ptr cinfo) { - char buffer[JMSG_LENGTH_MAX]; +static void TIFFjpeg_output_message(j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo, buffer); - TIFFWarningExtR(((JPEGState *)cinfo)->tif, "JPEGLib", "%s", - buffer); + (*cinfo->err->format_message)(cinfo, buffer); + TIFFWarningExtR(((JPEGState *)cinfo)->tif, "JPEGLib", "%s", buffer); } /* Avoid the risk of denial-of-service on crafted JPEGs with an insane */ @@ -292,23 +298,26 @@ static void TIFFjpeg_output_message(j_common_ptr cinfo) { /* See * http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */ -static void TIFFjpeg_progress_monitor(j_common_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */ - if (cinfo->is_decompressor) { - const int scan_no = ((j_decompress_ptr)cinfo)->input_scan_number; - if (scan_no >= sp->otherSettings.max_allowed_scan_number) { - TIFFErrorExtR( - ((JPEGState *)cinfo)->tif, - "TIFFjpeg_progress_monitor", - "Scan number %d exceeds maximum scans (%d). This limit " - "can be raised through the LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER " - "environment variable.", - scan_no, sp->otherSettings.max_allowed_scan_number); - - jpeg_abort(cinfo); /* clean up libjpeg state */ - LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ +static void TIFFjpeg_progress_monitor(j_common_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */ + if (cinfo->is_decompressor) + { + const int scan_no = ((j_decompress_ptr)cinfo)->input_scan_number; + if (scan_no >= sp->otherSettings.max_allowed_scan_number) + { + TIFFErrorExtR( + ((JPEGState *)cinfo)->tif, "TIFFjpeg_progress_monitor", + "Scan number %d exceeds maximum scans (%d). This limit " + "can be raised through the " + "LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER " + "environment variable.", + scan_no, sp->otherSettings.max_allowed_scan_number); + + jpeg_abort(cinfo); /* clean up libjpeg state */ + LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */ + } } - } } /* @@ -320,153 +329,172 @@ static void TIFFjpeg_progress_monitor(j_common_ptr cinfo) { #define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op)) #define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op), 1)) -static int TIFFjpeg_create_compress(JPEGState *sp) { - /* initialize JPEG error handling */ - sp->cinfo.c.err = jpeg_std_error(&sp->err); - sp->err.error_exit = TIFFjpeg_error_exit; - sp->err.output_message = TIFFjpeg_output_message; +static int TIFFjpeg_create_compress(JPEGState *sp) +{ + /* initialize JPEG error handling */ + sp->cinfo.c.err = jpeg_std_error(&sp->err); + sp->err.error_exit = TIFFjpeg_error_exit; + sp->err.output_message = TIFFjpeg_output_message; - /* set client_data to avoid UMR warning from tools like Purify */ - sp->cinfo.c.client_data = NULL; + /* set client_data to avoid UMR warning from tools like Purify */ + sp->cinfo.c.client_data = NULL; - return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c)); + return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c)); } -static int TIFFjpeg_create_decompress(JPEGState *sp) { - /* initialize JPEG error handling */ - sp->cinfo.d.err = jpeg_std_error(&sp->err); - sp->err.error_exit = TIFFjpeg_error_exit; - sp->err.output_message = TIFFjpeg_output_message; +static int TIFFjpeg_create_decompress(JPEGState *sp) +{ + /* initialize JPEG error handling */ + sp->cinfo.d.err = jpeg_std_error(&sp->err); + sp->err.error_exit = TIFFjpeg_error_exit; + sp->err.output_message = TIFFjpeg_output_message; - /* set client_data to avoid UMR warning from tools like Purify */ - sp->cinfo.d.client_data = NULL; + /* set client_data to avoid UMR warning from tools like Purify */ + sp->cinfo.d.client_data = NULL; - return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d)); + return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d)); } -static int TIFFjpeg_set_defaults(JPEGState *sp) { - return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c)); +static int TIFFjpeg_set_defaults(JPEGState *sp) +{ + return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c)); } -static int TIFFjpeg_set_colorspace(JPEGState *sp, J_COLOR_SPACE colorspace) { - return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace)); +static int TIFFjpeg_set_colorspace(JPEGState *sp, J_COLOR_SPACE colorspace) +{ + return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace)); } static int TIFFjpeg_set_quality(JPEGState *sp, int quality, - boolean force_baseline) { - return CALLVJPEG(sp, jpeg_set_quality(&sp->cinfo.c, quality, force_baseline)); + boolean force_baseline) +{ + return CALLVJPEG(sp, + jpeg_set_quality(&sp->cinfo.c, quality, force_baseline)); } -static int TIFFjpeg_suppress_tables(JPEGState *sp, boolean suppress) { - return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress)); +static int TIFFjpeg_suppress_tables(JPEGState *sp, boolean suppress) +{ + return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress)); } -static int TIFFjpeg_start_compress(JPEGState *sp, boolean write_all_tables) { - return CALLVJPEG(sp, jpeg_start_compress(&sp->cinfo.c, write_all_tables)); +static int TIFFjpeg_start_compress(JPEGState *sp, boolean write_all_tables) +{ + return CALLVJPEG(sp, jpeg_start_compress(&sp->cinfo.c, write_all_tables)); } static int TIFFjpeg_write_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines, - int num_lines) { + int num_lines) +{ #if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 - return CALLJPEG(sp, -1, - (int)jpeg12_write_scanlines(&sp->cinfo.c, scanlines, - (JDIMENSION)num_lines)); + return CALLJPEG(sp, -1, + (int)jpeg12_write_scanlines(&sp->cinfo.c, scanlines, + (JDIMENSION)num_lines)); #else - return CALLJPEG(sp, -1, - (int)jpeg_write_scanlines(&sp->cinfo.c, scanlines, - (JDIMENSION)num_lines)); + return CALLJPEG(sp, -1, + (int)jpeg_write_scanlines(&sp->cinfo.c, scanlines, + (JDIMENSION)num_lines)); #endif } static int TIFFjpeg_write_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data, - int num_lines) { + int num_lines) +{ #if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 - return CALLJPEG( - sp, -1, - (int)jpeg12_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines)); + return CALLJPEG( + sp, -1, + (int)jpeg12_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines)); #else - return CALLJPEG( - sp, -1, - (int)jpeg_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines)); + return CALLJPEG( + sp, -1, + (int)jpeg_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines)); #endif } -static int TIFFjpeg_finish_compress(JPEGState *sp) { - return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c)); +static int TIFFjpeg_finish_compress(JPEGState *sp) +{ + return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c)); } -static int TIFFjpeg_write_tables(JPEGState *sp) { - return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c)); +static int TIFFjpeg_write_tables(JPEGState *sp) +{ + return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c)); } -static int TIFFjpeg_read_header(JPEGState *sp, boolean require_image) { - return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image)); +static int TIFFjpeg_read_header(JPEGState *sp, boolean require_image) +{ + return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image)); } -static int TIFFjpeg_has_multiple_scans(JPEGState *sp) { - return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d)); +static int TIFFjpeg_has_multiple_scans(JPEGState *sp) +{ + return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d)); } -static int TIFFjpeg_start_decompress(JPEGState *sp) { - const char *sz_max_allowed_scan_number; - /* progress monitor */ - sp->cinfo.d.progress = &sp->progress; - sp->progress.progress_monitor = TIFFjpeg_progress_monitor; - sp->otherSettings.max_allowed_scan_number = 100; - sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER"); - if (sz_max_allowed_scan_number) - sp->otherSettings.max_allowed_scan_number = - atoi(sz_max_allowed_scan_number); +static int TIFFjpeg_start_decompress(JPEGState *sp) +{ + const char *sz_max_allowed_scan_number; + /* progress monitor */ + sp->cinfo.d.progress = &sp->progress; + sp->progress.progress_monitor = TIFFjpeg_progress_monitor; + sp->otherSettings.max_allowed_scan_number = 100; + sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER"); + if (sz_max_allowed_scan_number) + sp->otherSettings.max_allowed_scan_number = + atoi(sz_max_allowed_scan_number); - return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); + return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d)); } -static int TIFFjpeg_read_scanlines(JPEGState *sp, - TIFF_JSAMPARRAY scanlines, - int max_lines) { +static int TIFFjpeg_read_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines, + int max_lines) +{ #if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 - return CALLJPEG( - sp, -1, - (int)jpeg12_read_scanlines(&sp->cinfo.d, scanlines, (JDIMENSION)max_lines)); + return CALLJPEG(sp, -1, + (int)jpeg12_read_scanlines(&sp->cinfo.d, scanlines, + (JDIMENSION)max_lines)); #else - return CALLJPEG( - sp, -1, - (int)jpeg_read_scanlines(&sp->cinfo.d, scanlines, (JDIMENSION)max_lines)); + return CALLJPEG(sp, -1, + (int)jpeg_read_scanlines(&sp->cinfo.d, scanlines, + (JDIMENSION)max_lines)); #endif } -static int TIFFjpeg_read_raw_data(JPEGState *sp, - TIFF_JSAMPIMAGE data, - int max_lines) { +static int TIFFjpeg_read_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data, + int max_lines) +{ #if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12 - return CALLJPEG( - sp, -1, - (int)jpeg12_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines)); + return CALLJPEG( + sp, -1, + (int)jpeg12_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines)); #else - return CALLJPEG( - sp, -1, - (int)jpeg_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines)); + return CALLJPEG( + sp, -1, + (int)jpeg_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines)); #endif } -static int TIFFjpeg_finish_decompress(JPEGState *sp) { - return CALLJPEG(sp, -1, (int)jpeg_finish_decompress(&sp->cinfo.d)); +static int TIFFjpeg_finish_decompress(JPEGState *sp) +{ + return CALLJPEG(sp, -1, (int)jpeg_finish_decompress(&sp->cinfo.d)); } -static int TIFFjpeg_abort(JPEGState *sp) { - return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm)); +static int TIFFjpeg_abort(JPEGState *sp) +{ + return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm)); } -static int TIFFjpeg_destroy(JPEGState *sp) { - return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm)); +static int TIFFjpeg_destroy(JPEGState *sp) +{ + return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm)); } static JSAMPARRAY TIFFjpeg_alloc_sarray(JPEGState *sp, int pool_id, JDIMENSION samplesperrow, - JDIMENSION numrows) { - return CALLJPEG(sp, (JSAMPARRAY)NULL, - (*sp->cinfo.comm.mem->alloc_sarray)(&sp->cinfo.comm, pool_id, - samplesperrow, numrows)); + JDIMENSION numrows) +{ + return CALLJPEG(sp, (JSAMPARRAY)NULL, + (*sp->cinfo.comm.mem->alloc_sarray)( + &sp->cinfo.comm, pool_id, samplesperrow, numrows)); } /* @@ -475,116 +503,128 @@ static JSAMPARRAY TIFFjpeg_alloc_sarray(JPEGState *sp, int pool_id, * libtiff output buffer. */ -static void std_init_destination(j_compress_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; - TIFF *tif = sp->tif; +static void std_init_destination(j_compress_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; - sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; + sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; + sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; } -static boolean std_empty_output_buffer(j_compress_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; - TIFF *tif = sp->tif; +static boolean std_empty_output_buffer(j_compress_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - /* the entire buffer has been filled */ - tif->tif_rawcc = tif->tif_rawdatasize; + /* the entire buffer has been filled */ + tif->tif_rawcc = tif->tif_rawdatasize; #ifdef IPPJ_HUFF - /* - * The Intel IPP performance library does not necessarily fill up - * the whole output buffer on each pass, so only dump out the parts - * that have been filled. - * http://trac.osgeo.org/gdal/wiki/JpegIPP - */ - if (sp->dest.free_in_buffer >= 0) { - tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer; - } + /* + * The Intel IPP performance library does not necessarily fill up + * the whole output buffer on each pass, so only dump out the parts + * that have been filled. + * http://trac.osgeo.org/gdal/wiki/JpegIPP + */ + if (sp->dest.free_in_buffer >= 0) + { + tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer; + } #endif - if (!TIFFFlushData1(tif)) - return FALSE; - sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; - sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return FALSE; + sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata; + sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize; - return (TRUE); + return (TRUE); } -static void std_term_destination(j_compress_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; - TIFF *tif = sp->tif; +static void std_term_destination(j_compress_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - tif->tif_rawcp = (uint8_t *)sp->dest.next_output_byte; - tif->tif_rawcc = tif->tif_rawdatasize - (tmsize_t)sp->dest.free_in_buffer; - /* NB: libtiff does the final buffer flush */ + tif->tif_rawcp = (uint8_t *)sp->dest.next_output_byte; + tif->tif_rawcc = tif->tif_rawdatasize - (tmsize_t)sp->dest.free_in_buffer; + /* NB: libtiff does the final buffer flush */ } -static void TIFFjpeg_data_dest(JPEGState *sp, TIFF *tif) { - (void)tif; - sp->cinfo.c.dest = &sp->dest; - sp->dest.init_destination = std_init_destination; - sp->dest.empty_output_buffer = std_empty_output_buffer; - sp->dest.term_destination = std_term_destination; +static void TIFFjpeg_data_dest(JPEGState *sp, TIFF *tif) +{ + (void)tif; + sp->cinfo.c.dest = &sp->dest; + sp->dest.init_destination = std_init_destination; + sp->dest.empty_output_buffer = std_empty_output_buffer; + sp->dest.term_destination = std_term_destination; } /* * Alternate destination manager for outputting to JPEGTables field. */ -static void tables_init_destination(j_compress_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; +static void tables_init_destination(j_compress_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; - /* while building, otherSettings.jpegtables_length is allocated buffer size */ - sp->dest.next_output_byte = (JOCTET *)sp->otherSettings.jpegtables; - sp->dest.free_in_buffer = (size_t)sp->otherSettings.jpegtables_length; + /* while building, otherSettings.jpegtables_length is allocated buffer size + */ + sp->dest.next_output_byte = (JOCTET *)sp->otherSettings.jpegtables; + sp->dest.free_in_buffer = (size_t)sp->otherSettings.jpegtables_length; } -static boolean tables_empty_output_buffer(j_compress_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; - void *newbuf; +static boolean tables_empty_output_buffer(j_compress_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; + void *newbuf; - /* the entire buffer has been filled; enlarge it by 1000 bytes */ - newbuf = _TIFFreallocExt(sp->tif, (void *)sp->otherSettings.jpegtables, + /* the entire buffer has been filled; enlarge it by 1000 bytes */ + newbuf = + _TIFFreallocExt(sp->tif, (void *)sp->otherSettings.jpegtables, (tmsize_t)(sp->otherSettings.jpegtables_length + 1000)); - if (newbuf == NULL) - ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); - sp->dest.next_output_byte = - (JOCTET *)newbuf + sp->otherSettings.jpegtables_length; - sp->dest.free_in_buffer = (size_t)1000; - sp->otherSettings.jpegtables = newbuf; - sp->otherSettings.jpegtables_length += 1000; - return (TRUE); -} - -static void tables_term_destination(j_compress_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; - - /* set tables length to number of bytes actually emitted */ - sp->otherSettings.jpegtables_length -= (uint32_t)sp->dest.free_in_buffer; -} - -static int TIFFjpeg_tables_dest(JPEGState *sp, TIFF *tif) { - (void)tif; - /* - * Allocate a working buffer for building tables. - * Initial size is 1000 bytes, which is usually adequate. - */ - if (sp->otherSettings.jpegtables) - _TIFFfreeExt(tif, sp->otherSettings.jpegtables); - sp->otherSettings.jpegtables_length = 1000; - sp->otherSettings.jpegtables = - (void *)_TIFFmallocExt(tif, (tmsize_t)sp->otherSettings.jpegtables_length); - if (sp->otherSettings.jpegtables == NULL) { - sp->otherSettings.jpegtables_length = 0; - TIFFErrorExtR(sp->tif, "TIFFjpeg_tables_dest", - "No space for JPEGTables"); - return (0); - } - sp->cinfo.c.dest = &sp->dest; - sp->dest.init_destination = tables_init_destination; - sp->dest.empty_output_buffer = tables_empty_output_buffer; - sp->dest.term_destination = tables_term_destination; - return (1); + if (newbuf == NULL) + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100); + sp->dest.next_output_byte = + (JOCTET *)newbuf + sp->otherSettings.jpegtables_length; + sp->dest.free_in_buffer = (size_t)1000; + sp->otherSettings.jpegtables = newbuf; + sp->otherSettings.jpegtables_length += 1000; + return (TRUE); +} + +static void tables_term_destination(j_compress_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; + + /* set tables length to number of bytes actually emitted */ + sp->otherSettings.jpegtables_length -= (uint32_t)sp->dest.free_in_buffer; +} + +static int TIFFjpeg_tables_dest(JPEGState *sp, TIFF *tif) +{ + (void)tif; + /* + * Allocate a working buffer for building tables. + * Initial size is 1000 bytes, which is usually adequate. + */ + if (sp->otherSettings.jpegtables) + _TIFFfreeExt(tif, sp->otherSettings.jpegtables); + sp->otherSettings.jpegtables_length = 1000; + sp->otherSettings.jpegtables = (void *)_TIFFmallocExt( + tif, (tmsize_t)sp->otherSettings.jpegtables_length); + if (sp->otherSettings.jpegtables == NULL) + { + sp->otherSettings.jpegtables_length = 0; + TIFFErrorExtR(sp->tif, "TIFFjpeg_tables_dest", + "No space for JPEGTables"); + return (0); + } + sp->cinfo.c.dest = &sp->dest; + sp->dest.init_destination = tables_init_destination; + sp->dest.empty_output_buffer = tables_empty_output_buffer; + sp->dest.term_destination = tables_term_destination; + return (1); } /* @@ -592,76 +632,86 @@ static int TIFFjpeg_tables_dest(JPEGState *sp, TIFF *tif) { * These routines supply compressed data to libjpeg. */ -static void std_init_source(j_decompress_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; - TIFF *tif = sp->tif; +static void std_init_source(j_decompress_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; + TIFF *tif = sp->tif; - sp->src.next_input_byte = (const JOCTET *)tif->tif_rawdata; - sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; + sp->src.next_input_byte = (const JOCTET *)tif->tif_rawdata; + sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; } -static boolean std_fill_input_buffer(j_decompress_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; - static const JOCTET dummy_EOI[2] = {0xFF, JPEG_EOI}; +static boolean std_fill_input_buffer(j_decompress_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; + static const JOCTET dummy_EOI[2] = {0xFF, JPEG_EOI}; #ifdef IPPJ_HUFF - /* - * The Intel IPP performance library does not necessarily read the whole - * input buffer in one pass, so it is possible to get here with data - * yet to read. - * - * We just return without doing anything, until the entire buffer has - * been read. - * http://trac.osgeo.org/gdal/wiki/JpegIPP - */ - if (sp->src.bytes_in_buffer > 0) { - return (TRUE); - } + /* + * The Intel IPP performance library does not necessarily read the whole + * input buffer in one pass, so it is possible to get here with data + * yet to read. + * + * We just return without doing anything, until the entire buffer has + * been read. + * http://trac.osgeo.org/gdal/wiki/JpegIPP + */ + if (sp->src.bytes_in_buffer > 0) + { + return (TRUE); + } #endif - /* - * Normally the whole strip/tile is read and so we don't need to do - * a fill. In the case of CHUNKY_STRIP_READ_SUPPORT we might not have - * all the data, but the rawdata is refreshed between scanlines and - * we push this into the io machinery in JPEGDecode(). - * http://trac.osgeo.org/gdal/ticket/3894 - */ + /* + * Normally the whole strip/tile is read and so we don't need to do + * a fill. In the case of CHUNKY_STRIP_READ_SUPPORT we might not have + * all the data, but the rawdata is refreshed between scanlines and + * we push this into the io machinery in JPEGDecode(). + * http://trac.osgeo.org/gdal/ticket/3894 + */ - WARNMS(cinfo, JWRN_JPEG_EOF); - /* insert a fake EOI marker */ - sp->src.next_input_byte = dummy_EOI; - sp->src.bytes_in_buffer = 2; - return (TRUE); + WARNMS(cinfo, JWRN_JPEG_EOF); + /* insert a fake EOI marker */ + sp->src.next_input_byte = dummy_EOI; + sp->src.bytes_in_buffer = 2; + return (TRUE); } -static void std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { - JPEGState *sp = (JPEGState *)cinfo; +static void std_skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + JPEGState *sp = (JPEGState *)cinfo; - if (num_bytes > 0) { - if ((size_t)num_bytes > sp->src.bytes_in_buffer) { - /* oops, buffer overrun */ - (void)std_fill_input_buffer(cinfo); - } else { - sp->src.next_input_byte += (size_t)num_bytes; - sp->src.bytes_in_buffer -= (size_t)num_bytes; + if (num_bytes > 0) + { + if ((size_t)num_bytes > sp->src.bytes_in_buffer) + { + /* oops, buffer overrun */ + (void)std_fill_input_buffer(cinfo); + } + else + { + sp->src.next_input_byte += (size_t)num_bytes; + sp->src.bytes_in_buffer -= (size_t)num_bytes; + } } - } } -static void std_term_source(j_decompress_ptr cinfo) { - /* No work necessary here */ - (void)cinfo; +static void std_term_source(j_decompress_ptr cinfo) +{ + /* No work necessary here */ + (void)cinfo; } -static void TIFFjpeg_data_src(JPEGState *sp) { - sp->cinfo.d.src = &sp->src; - sp->src.init_source = std_init_source; - sp->src.fill_input_buffer = std_fill_input_buffer; - sp->src.skip_input_data = std_skip_input_data; - sp->src.resync_to_restart = jpeg_resync_to_restart; - sp->src.term_source = std_term_source; - sp->src.bytes_in_buffer = 0; /* for safety */ - sp->src.next_input_byte = NULL; +static void TIFFjpeg_data_src(JPEGState *sp) +{ + sp->cinfo.d.src = &sp->src; + sp->src.init_source = std_init_source; + sp->src.fill_input_buffer = std_fill_input_buffer; + sp->src.skip_input_data = std_skip_input_data; + sp->src.resync_to_restart = jpeg_resync_to_restart; + sp->src.term_source = std_term_source; + sp->src.bytes_in_buffer = 0; /* for safety */ + sp->src.next_input_byte = NULL; } /* @@ -669,16 +719,18 @@ static void TIFFjpeg_data_src(JPEGState *sp) { * We can share all the code except for the init routine. */ -static void tables_init_source(j_decompress_ptr cinfo) { - JPEGState *sp = (JPEGState *)cinfo; +static void tables_init_source(j_decompress_ptr cinfo) +{ + JPEGState *sp = (JPEGState *)cinfo; - sp->src.next_input_byte = (const JOCTET *)sp->otherSettings.jpegtables; - sp->src.bytes_in_buffer = (size_t)sp->otherSettings.jpegtables_length; + sp->src.next_input_byte = (const JOCTET *)sp->otherSettings.jpegtables; + sp->src.bytes_in_buffer = (size_t)sp->otherSettings.jpegtables_length; } -static void TIFFjpeg_tables_src(JPEGState *sp) { - TIFFjpeg_data_src(sp); - sp->src.init_source = tables_init_source; +static void TIFFjpeg_tables_src(JPEGState *sp) +{ + TIFFjpeg_data_src(sp); + sp->src.init_source = tables_init_source; } /* @@ -689,24 +741,26 @@ static void TIFFjpeg_tables_src(JPEGState *sp) { * This is also a handy place to compute samplesperclump, bytesperline. */ static int alloc_downsampled_buffers(TIFF *tif, jpeg_component_info *comp_info, - int num_components) { - JPEGState *sp = JState(tif); - int ci; - jpeg_component_info *compptr; - TIFF_JSAMPARRAY buf; - int samples_per_clump = 0; - - for (ci = 0, compptr = comp_info; ci < num_components; ci++, compptr++) { - samples_per_clump += compptr->h_samp_factor * compptr->v_samp_factor; - buf = (TIFF_JSAMPARRAY)TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE, - compptr->width_in_blocks * DCTSIZE, - (JDIMENSION)(compptr->v_samp_factor * DCTSIZE)); - if (buf == NULL) - return (0); - sp->ds_buffer[ci] = buf; - } - sp->samplesperclump = samples_per_clump; - return (1); + int num_components) +{ + JPEGState *sp = JState(tif); + int ci; + jpeg_component_info *compptr; + TIFF_JSAMPARRAY buf; + int samples_per_clump = 0; + + for (ci = 0, compptr = comp_info; ci < num_components; ci++, compptr++) + { + samples_per_clump += compptr->h_samp_factor * compptr->v_samp_factor; + buf = (TIFF_JSAMPARRAY)TIFFjpeg_alloc_sarray( + sp, JPOOL_IMAGE, compptr->width_in_blocks * DCTSIZE, + (JDIMENSION)(compptr->v_samp_factor * DCTSIZE)); + if (buf == NULL) + return (0); + sp->ds_buffer[ci] = buf; + } + sp->samplesperclump = samples_per_clump; + return (1); } /* @@ -727,15 +781,16 @@ static int alloc_downsampled_buffers(TIFF *tif, jpeg_component_info *comp_info, #define JPEG_MARKER_DRI 0xDD #define JPEG_MARKER_APP0 0xE0 #define JPEG_MARKER_COM 0xFE -struct JPEGFixupTagsSubsamplingData { - TIFF *tif; - void *buffer; - uint32_t buffersize; - uint8_t *buffercurrentbyte; - uint32_t bufferbytesleft; - uint64_t fileoffset; - uint64_t filebytesleft; - uint8_t filepositioned; +struct JPEGFixupTagsSubsamplingData +{ + TIFF *tif; + void *buffer; + uint32_t buffersize; + uint8_t *buffercurrentbyte; + uint32_t bufferbytesleft; + uint64_t fileoffset; + uint64_t filebytesleft; + uint8_t filepositioned; }; static void JPEGFixupTagsSubsampling(TIFF *tif); static int @@ -752,306 +807,343 @@ JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data, #endif -static int JPEGFixupTags(TIFF *tif) { +static int JPEGFixupTags(TIFF *tif) +{ #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING - JPEGState *sp = JState(tif); - if ((tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) && - (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) && - (tif->tif_dir.td_samplesperpixel == 3) && - !sp->otherSettings.ycbcrsampling_fetched) - JPEGFixupTagsSubsampling(tif); + JPEGState *sp = JState(tif); + if ((tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) && + (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) && + (tif->tif_dir.td_samplesperpixel == 3) && + !sp->otherSettings.ycbcrsampling_fetched) + JPEGFixupTagsSubsampling(tif); #endif - return (1); + return (1); } #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING -static void JPEGFixupTagsSubsampling(TIFF *tif) { - /* - * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in - * the TIFF tags, but still use non-default (2,2) values within the jpeg - * data stream itself. In order for TIFF applications to work properly - * - for instance to get the strip buffer size right - it is imperative - * that the subsampling be available before we start reading the image - * data normally. This function will attempt to analyze the first strip in - * order to get the sampling values from the jpeg data stream. - * - * Note that JPEGPreDeocode() will produce a fairly loud warning when the - * discovered sampling does not match the default sampling (2,2) or whatever - * was actually in the tiff tags. - * - * See the bug in bugzilla for details: - * - * http://bugzilla.remotesensing.org/show_bug.cgi?id=168 - * - * Frank Warmerdam, July 2002 - * Joris Van Damme, May 2007 - */ - static const char module[] = "JPEGFixupTagsSubsampling"; - struct JPEGFixupTagsSubsamplingData m; - uint64_t fileoffset = TIFFGetStrileOffset(tif, 0); - - if (fileoffset == 0) { - /* Do not even try to check if the first strip/tile does not - yet exist, as occurs when GDAL has created a new NULL file - for instance. */ - return; - } - - m.tif = tif; - m.buffersize = 2048; - m.buffer = _TIFFmallocExt(tif, m.buffersize); - if (m.buffer == NULL) { - TIFFWarningExtR(tif, module, - "Unable to allocate memory for auto-correcting of " - "subsampling values; auto-correcting skipped"); - return; - } - m.buffercurrentbyte = NULL; - m.bufferbytesleft = 0; - m.fileoffset = fileoffset; - m.filepositioned = 0; - m.filebytesleft = TIFFGetStrileByteCount(tif, 0); - if (!JPEGFixupTagsSubsamplingSec(&m)) - TIFFWarningExtR( - tif, module, - "Unable to auto-correct subsampling values, likely corrupt JPEG " - "compressed data in first strip/tile; auto-correcting skipped"); - _TIFFfreeExt(tif, m.buffer); +static void JPEGFixupTagsSubsampling(TIFF *tif) +{ + /* + * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in + * the TIFF tags, but still use non-default (2,2) values within the jpeg + * data stream itself. In order for TIFF applications to work properly + * - for instance to get the strip buffer size right - it is imperative + * that the subsampling be available before we start reading the image + * data normally. This function will attempt to analyze the first strip in + * order to get the sampling values from the jpeg data stream. + * + * Note that JPEGPreDeocode() will produce a fairly loud warning when the + * discovered sampling does not match the default sampling (2,2) or whatever + * was actually in the tiff tags. + * + * See the bug in bugzilla for details: + * + * http://bugzilla.remotesensing.org/show_bug.cgi?id=168 + * + * Frank Warmerdam, July 2002 + * Joris Van Damme, May 2007 + */ + static const char module[] = "JPEGFixupTagsSubsampling"; + struct JPEGFixupTagsSubsamplingData m; + uint64_t fileoffset = TIFFGetStrileOffset(tif, 0); + + if (fileoffset == 0) + { + /* Do not even try to check if the first strip/tile does not + yet exist, as occurs when GDAL has created a new NULL file + for instance. */ + return; + } + + m.tif = tif; + m.buffersize = 2048; + m.buffer = _TIFFmallocExt(tif, m.buffersize); + if (m.buffer == NULL) + { + TIFFWarningExtR(tif, module, + "Unable to allocate memory for auto-correcting of " + "subsampling values; auto-correcting skipped"); + return; + } + m.buffercurrentbyte = NULL; + m.bufferbytesleft = 0; + m.fileoffset = fileoffset; + m.filepositioned = 0; + m.filebytesleft = TIFFGetStrileByteCount(tif, 0); + if (!JPEGFixupTagsSubsamplingSec(&m)) + TIFFWarningExtR( + tif, module, + "Unable to auto-correct subsampling values, likely corrupt JPEG " + "compressed data in first strip/tile; auto-correcting skipped"); + _TIFFfreeExt(tif, m.buffer); } static int -JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data) { - static const char module[] = "JPEGFixupTagsSubsamplingSec"; - uint8_t m; - while (1) { - while (1) { - if (!JPEGFixupTagsSubsamplingReadByte(data, &m)) - return (0); - if (m == 255) - break; - } - while (1) { - if (!JPEGFixupTagsSubsamplingReadByte(data, &m)) - return (0); - if (m != 255) - break; - } - switch (m) { - case JPEG_MARKER_SOI: - /* this type of marker has no data and should be skipped */ - break; - case JPEG_MARKER_COM: - case JPEG_MARKER_APP0: - case JPEG_MARKER_APP0 + 1: - case JPEG_MARKER_APP0 + 2: - case JPEG_MARKER_APP0 + 3: - case JPEG_MARKER_APP0 + 4: - case JPEG_MARKER_APP0 + 5: - case JPEG_MARKER_APP0 + 6: - case JPEG_MARKER_APP0 + 7: - case JPEG_MARKER_APP0 + 8: - case JPEG_MARKER_APP0 + 9: - case JPEG_MARKER_APP0 + 10: - case JPEG_MARKER_APP0 + 11: - case JPEG_MARKER_APP0 + 12: - case JPEG_MARKER_APP0 + 13: - case JPEG_MARKER_APP0 + 14: - case JPEG_MARKER_APP0 + 15: - case JPEG_MARKER_DQT: - case JPEG_MARKER_SOS: - case JPEG_MARKER_DHT: - case JPEG_MARKER_DRI: - /* this type of marker has data, but it has no use to us and should be - * skipped */ - { - uint16_t n; - if (!JPEGFixupTagsSubsamplingReadWord(data, &n)) - return (0); - if (n < 2) - return (0); - n -= 2; - if (n > 0) - JPEGFixupTagsSubsamplingSkip(data, n); - } - break; - case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */ - case JPEG_MARKER_SOF1: /* Extended sequential Huffman */ - case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed by - TechNote, but that doesn't hurt supporting it */ - case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */ - case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not allowed by - TechNote, but that doesn't hurt supporting it */ - /* this marker contains the subsampling factors we're scanning for */ - { - uint16_t n; - uint16_t o; - uint8_t p; - uint8_t ph, pv; - if (!JPEGFixupTagsSubsamplingReadWord(data, &n)) - return (0); - if (n != 8 + data->tif->tif_dir.td_samplesperpixel * 3) - return (0); - JPEGFixupTagsSubsamplingSkip(data, 7); - if (!JPEGFixupTagsSubsamplingReadByte(data, &p)) - return (0); - ph = (p >> 4); - pv = (p & 15); - JPEGFixupTagsSubsamplingSkip(data, 1); - for (o = 1; o < data->tif->tif_dir.td_samplesperpixel; o++) { - JPEGFixupTagsSubsamplingSkip(data, 1); - if (!JPEGFixupTagsSubsamplingReadByte(data, &p)) - return (0); - if (p != 0x11) { - TIFFWarningExtR(data->tif, module, - "Subsampling values inside JPEG compressed data " - "have no TIFF equivalent, auto-correction of TIFF " - "subsampling values failed"); - return (1); - } - JPEGFixupTagsSubsamplingSkip(data, 1); +JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data) +{ + static const char module[] = "JPEGFixupTagsSubsamplingSec"; + uint8_t m; + while (1) + { + while (1) + { + if (!JPEGFixupTagsSubsamplingReadByte(data, &m)) + return (0); + if (m == 255) + break; } - if (((ph != 1) && (ph != 2) && (ph != 4)) || - ((pv != 1) && (pv != 2) && (pv != 4))) { - TIFFWarningExtR( - data->tif, module, - "Subsampling values inside JPEG compressed data have no TIFF " - "equivalent, auto-correction of TIFF subsampling values failed"); - return (1); + while (1) + { + if (!JPEGFixupTagsSubsamplingReadByte(data, &m)) + return (0); + if (m != 255) + break; } - if ((ph != data->tif->tif_dir.td_ycbcrsubsampling[0]) || - (pv != data->tif->tif_dir.td_ycbcrsubsampling[1])) { - TIFFWarningExtR( - data->tif, module, - "Auto-corrected former TIFF subsampling values [%" PRIu16 - ",%" PRIu16 "] to match subsampling values inside JPEG " - "compressed data [%" PRIu8 ",%" PRIu8 "]", - data->tif->tif_dir.td_ycbcrsubsampling[0], - data->tif->tif_dir.td_ycbcrsubsampling[1], ph, pv); - data->tif->tif_dir.td_ycbcrsubsampling[0] = ph; - data->tif->tif_dir.td_ycbcrsubsampling[1] = pv; + switch (m) + { + case JPEG_MARKER_SOI: + /* this type of marker has no data and should be skipped */ + break; + case JPEG_MARKER_COM: + case JPEG_MARKER_APP0: + case JPEG_MARKER_APP0 + 1: + case JPEG_MARKER_APP0 + 2: + case JPEG_MARKER_APP0 + 3: + case JPEG_MARKER_APP0 + 4: + case JPEG_MARKER_APP0 + 5: + case JPEG_MARKER_APP0 + 6: + case JPEG_MARKER_APP0 + 7: + case JPEG_MARKER_APP0 + 8: + case JPEG_MARKER_APP0 + 9: + case JPEG_MARKER_APP0 + 10: + case JPEG_MARKER_APP0 + 11: + case JPEG_MARKER_APP0 + 12: + case JPEG_MARKER_APP0 + 13: + case JPEG_MARKER_APP0 + 14: + case JPEG_MARKER_APP0 + 15: + case JPEG_MARKER_DQT: + case JPEG_MARKER_SOS: + case JPEG_MARKER_DHT: + case JPEG_MARKER_DRI: + /* this type of marker has data, but it has no use to us and + * should be skipped */ + { + uint16_t n; + if (!JPEGFixupTagsSubsamplingReadWord(data, &n)) + return (0); + if (n < 2) + return (0); + n -= 2; + if (n > 0) + JPEGFixupTagsSubsamplingSkip(data, n); + } + break; + case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */ + case JPEG_MARKER_SOF1: /* Extended sequential Huffman */ + case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed + by TechNote, but that doesn't hurt + supporting it */ + case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */ + case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not + allowed by TechNote, but that doesn't + hurt supporting it */ + /* this marker contains the subsampling factors we're scanning + * for */ + { + uint16_t n; + uint16_t o; + uint8_t p; + uint8_t ph, pv; + if (!JPEGFixupTagsSubsamplingReadWord(data, &n)) + return (0); + if (n != 8 + data->tif->tif_dir.td_samplesperpixel * 3) + return (0); + JPEGFixupTagsSubsamplingSkip(data, 7); + if (!JPEGFixupTagsSubsamplingReadByte(data, &p)) + return (0); + ph = (p >> 4); + pv = (p & 15); + JPEGFixupTagsSubsamplingSkip(data, 1); + for (o = 1; o < data->tif->tif_dir.td_samplesperpixel; o++) + { + JPEGFixupTagsSubsamplingSkip(data, 1); + if (!JPEGFixupTagsSubsamplingReadByte(data, &p)) + return (0); + if (p != 0x11) + { + TIFFWarningExtR(data->tif, module, + "Subsampling values inside JPEG " + "compressed data " + "have no TIFF equivalent, " + "auto-correction of TIFF " + "subsampling values failed"); + return (1); + } + JPEGFixupTagsSubsamplingSkip(data, 1); + } + if (((ph != 1) && (ph != 2) && (ph != 4)) || + ((pv != 1) && (pv != 2) && (pv != 4))) + { + TIFFWarningExtR(data->tif, module, + "Subsampling values inside JPEG " + "compressed data have no TIFF " + "equivalent, auto-correction of TIFF " + "subsampling values failed"); + return (1); + } + if ((ph != data->tif->tif_dir.td_ycbcrsubsampling[0]) || + (pv != data->tif->tif_dir.td_ycbcrsubsampling[1])) + { + TIFFWarningExtR( + data->tif, module, + "Auto-corrected former TIFF subsampling values " + "[%" PRIu16 ",%" PRIu16 + "] to match subsampling values inside JPEG " + "compressed data [%" PRIu8 ",%" PRIu8 "]", + data->tif->tif_dir.td_ycbcrsubsampling[0], + data->tif->tif_dir.td_ycbcrsubsampling[1], ph, pv); + data->tif->tif_dir.td_ycbcrsubsampling[0] = ph; + data->tif->tif_dir.td_ycbcrsubsampling[1] = pv; + } + } + return (1); + default: + return (0); } - } - return (1); - default: - return (0); } - } } static int JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data, - uint8_t *result) { - if (data->bufferbytesleft == 0) { - uint32_t m; - if (data->filebytesleft == 0) - return (0); - if (!data->filepositioned) { - if (TIFFSeekFile(data->tif, data->fileoffset, SEEK_SET) == (toff_t)-1) { - return 0; - } - data->filepositioned = 1; - } - m = data->buffersize; - if ((uint64_t)m > data->filebytesleft) - m = (uint32_t)data->filebytesleft; - assert(m < 0x80000000UL); - if (TIFFReadFile(data->tif, data->buffer, (tmsize_t)m) != (tmsize_t)m) - return (0); - data->buffercurrentbyte = data->buffer; - data->bufferbytesleft = m; - data->fileoffset += m; - data->filebytesleft -= m; - } - *result = *data->buffercurrentbyte; - data->buffercurrentbyte++; - data->bufferbytesleft--; - return (1); + uint8_t *result) +{ + if (data->bufferbytesleft == 0) + { + uint32_t m; + if (data->filebytesleft == 0) + return (0); + if (!data->filepositioned) + { + if (TIFFSeekFile(data->tif, data->fileoffset, SEEK_SET) == + (toff_t)-1) + { + return 0; + } + data->filepositioned = 1; + } + m = data->buffersize; + if ((uint64_t)m > data->filebytesleft) + m = (uint32_t)data->filebytesleft; + assert(m < 0x80000000UL); + if (TIFFReadFile(data->tif, data->buffer, (tmsize_t)m) != (tmsize_t)m) + return (0); + data->buffercurrentbyte = data->buffer; + data->bufferbytesleft = m; + data->fileoffset += m; + data->filebytesleft -= m; + } + *result = *data->buffercurrentbyte; + data->buffercurrentbyte++; + data->bufferbytesleft--; + return (1); } static int JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data, - uint16_t *result) { - uint8_t ma; - uint8_t mb; - if (!JPEGFixupTagsSubsamplingReadByte(data, &ma)) - return (0); - if (!JPEGFixupTagsSubsamplingReadByte(data, &mb)) - return (0); - *result = (ma << 8) | mb; - return (1); + uint16_t *result) +{ + uint8_t ma; + uint8_t mb; + if (!JPEGFixupTagsSubsamplingReadByte(data, &ma)) + return (0); + if (!JPEGFixupTagsSubsamplingReadByte(data, &mb)) + return (0); + *result = (ma << 8) | mb; + return (1); } static void JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data, - uint16_t skiplength) { - if ((uint32_t)skiplength <= data->bufferbytesleft) { - data->buffercurrentbyte += skiplength; - data->bufferbytesleft -= skiplength; - } else { - uint16_t m; - m = (uint16_t)(skiplength - data->bufferbytesleft); - if (m <= data->filebytesleft) { - data->bufferbytesleft = 0; - data->fileoffset += m; - data->filebytesleft -= m; - data->filepositioned = 0; - } else { - data->bufferbytesleft = 0; - data->filebytesleft = 0; - } - } + uint16_t skiplength) +{ + if ((uint32_t)skiplength <= data->bufferbytesleft) + { + data->buffercurrentbyte += skiplength; + data->bufferbytesleft -= skiplength; + } + else + { + uint16_t m; + m = (uint16_t)(skiplength - data->bufferbytesleft); + if (m <= data->filebytesleft) + { + data->bufferbytesleft = 0; + data->fileoffset += m; + data->filebytesleft -= m; + data->filepositioned = 0; + } + else + { + data->bufferbytesleft = 0; + data->filebytesleft = 0; + } + } } #endif -static int JPEGSetupDecode(TIFF *tif) { - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; +static int JPEGSetupDecode(TIFF *tif) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; #if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) - if (tif->tif_dir.td_bitspersample == 12) { - /* We pass a pointer to a copy of otherSettings, since */ - /* TIFFReInitJPEG_12() will clear sp */ - JPEGOtherSettings savedOtherSettings = sp->otherSettings; - return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 0); - } + if (tif->tif_dir.td_bitspersample == 12) + { + /* We pass a pointer to a copy of otherSettings, since */ + /* TIFFReInitJPEG_12() will clear sp */ + JPEGOtherSettings savedOtherSettings = sp->otherSettings; + return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 0); + } #endif - JPEGInitializeLibJPEG(tif, TRUE); - - assert(sp != NULL); - assert(sp->cinfo.comm.is_decompressor); - - /* Read JPEGTables if it is present */ - if (TIFFFieldSet(tif, FIELD_JPEGTABLES)) { - TIFFjpeg_tables_src(sp); - if (TIFFjpeg_read_header(sp, FALSE) != JPEG_HEADER_TABLES_ONLY) { - TIFFErrorExtR(tif, "JPEGSetupDecode", - "Bogus JPEGTables field"); - return (0); - } - } - - /* Grab parameters that are same for all strips/tiles */ - sp->photometric = td->td_photometric; - switch (sp->photometric) { - case PHOTOMETRIC_YCBCR: - sp->h_sampling = td->td_ycbcrsubsampling[0]; - sp->v_sampling = td->td_ycbcrsubsampling[1]; - break; - default: - /* TIFF 6.0 forbids subsampling of all other color spaces */ - sp->h_sampling = 1; - sp->v_sampling = 1; - break; - } - - /* Set up for reading normal data */ - TIFFjpeg_data_src(sp); - tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ - return (1); + JPEGInitializeLibJPEG(tif, TRUE); + + assert(sp != NULL); + assert(sp->cinfo.comm.is_decompressor); + + /* Read JPEGTables if it is present */ + if (TIFFFieldSet(tif, FIELD_JPEGTABLES)) + { + TIFFjpeg_tables_src(sp); + if (TIFFjpeg_read_header(sp, FALSE) != JPEG_HEADER_TABLES_ONLY) + { + TIFFErrorExtR(tif, "JPEGSetupDecode", "Bogus JPEGTables field"); + return (0); + } + } + + /* Grab parameters that are same for all strips/tiles */ + sp->photometric = td->td_photometric; + switch (sp->photometric) + { + case PHOTOMETRIC_YCBCR: + sp->h_sampling = td->td_ycbcrsubsampling[0]; + sp->v_sampling = td->td_ycbcrsubsampling[1]; + break; + default: + /* TIFF 6.0 forbids subsampling of all other color spaces */ + sp->h_sampling = 1; + sp->v_sampling = 1; + break; + } + + /* Set up for reading normal data */ + TIFFjpeg_data_src(sp); + tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */ + return (1); } /* Returns 1 if the full strip should be read, even when doing scanline per */ @@ -1061,269 +1153,303 @@ static int JPEGSetupDecode(TIFF *tif) { /* Only reads tif->tif_dir.td_bitspersample, tif->tif_rawdata and */ /* tif->tif_rawcc members. */ /* Can be called independently of the usual setup/predecode/decode states */ -int TIFFJPEGIsFullStripRequired(TIFF *tif) { - int ret; - JPEGState state; +int TIFFJPEGIsFullStripRequired(TIFF *tif) +{ + int ret; + JPEGState state; #if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) - if (tif->tif_dir.td_bitspersample == 12) - return TIFFJPEGIsFullStripRequired_12(tif); + if (tif->tif_dir.td_bitspersample == 12) + return TIFFJPEGIsFullStripRequired_12(tif); #endif - memset(&state, 0, sizeof(JPEGState)); - state.tif = tif; + memset(&state, 0, sizeof(JPEGState)); + state.tif = tif; - TIFFjpeg_create_decompress(&state); + TIFFjpeg_create_decompress(&state); - TIFFjpeg_data_src(&state); + TIFFjpeg_data_src(&state); - if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK) { - TIFFjpeg_destroy(&state); - return (0); - } - ret = TIFFjpeg_has_multiple_scans(&state); + if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK) + { + TIFFjpeg_destroy(&state); + return (0); + } + ret = TIFFjpeg_has_multiple_scans(&state); - TIFFjpeg_destroy(&state); + TIFFjpeg_destroy(&state); - return ret; + return ret; } /* * Set up for decoding a strip or tile. */ -/*ARGSUSED*/ static int JPEGPreDecode(TIFF *tif, uint16_t s) { - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGPreDecode"; - uint32_t segment_width, segment_height; - int downsampled_output; - int ci; - - assert(sp != NULL); - - if (sp->cinfo.comm.is_decompressor == 0) { - tif->tif_setupdecode(tif); - } - - assert(sp->cinfo.comm.is_decompressor); - /* - * Reset decoder state from any previous strip/tile, - * in case application didn't read the whole strip. - */ - if (!TIFFjpeg_abort(sp)) - return (0); - /* - * Read the header for this strip/tile. - */ - - if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) - return (0); - - tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; - - /* - * Check image parameters and set decompression parameters. - */ - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - sp->bytesperline = TIFFTileRowSize(tif); - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - sp->bytesperline = TIFFScanlineSize(tif); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { +/*ARGSUSED*/ static int JPEGPreDecode(TIFF *tif, uint16_t s) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGPreDecode"; + uint32_t segment_width, segment_height; + int downsampled_output; + int ci; + + assert(sp != NULL); + + if (sp->cinfo.comm.is_decompressor == 0) + { + tif->tif_setupdecode(tif); + } + + assert(sp->cinfo.comm.is_decompressor); + /* + * Reset decoder state from any previous strip/tile, + * in case application didn't read the whole strip. + */ + if (!TIFFjpeg_abort(sp)) + return (0); /* - * For PC 2, scale down the expected strip/tile size - * to match a downsampled component + * Read the header for this strip/tile. */ - segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); - segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); - } - if (sp->cinfo.d.image_width < segment_width || - sp->cinfo.d.image_height < segment_height) { - TIFFWarningExtR(tif, module, - "Improper JPEG strip/tile size, " - "expected %" PRIu32 "x%" PRIu32 ", got %ux%u", - segment_width, segment_height, sp->cinfo.d.image_width, - sp->cinfo.d.image_height); - } - if (sp->cinfo.d.image_width == segment_width && - sp->cinfo.d.image_height > segment_height && - tif->tif_row + segment_height == td->td_imagelength && !isTiled(tif)) { - /* Some files have a last strip, that should be truncated, */ - /* but their JPEG codestream has still the maximum strip */ - /* height. Warn about this as this is non compliant, but */ - /* we can safely recover from that. */ - TIFFWarningExtR(tif, module, - "JPEG strip size exceeds expected dimensions," - " expected %" PRIu32 "x%" PRIu32 ", got %ux%u", - segment_width, segment_height, sp->cinfo.d.image_width, - sp->cinfo.d.image_height); - } else if (sp->cinfo.d.image_width > segment_width || - sp->cinfo.d.image_height > segment_height) { + + if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK) + return (0); + + tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + /* - * This case could be dangerous, if the strip or tile size has - * been reported as less than the amount of data jpeg will - * return, some potential security issues arise. Catch this - * case and error out. + * Check image parameters and set decompression parameters. */ - TIFFErrorExtR(tif, module, - "JPEG strip/tile size exceeds expected dimensions," - " expected %" PRIu32 "x%" PRIu32 ", got %ux%u", - segment_width, segment_height, sp->cinfo.d.image_width, - sp->cinfo.d.image_height); - return (0); - } - if (sp->cinfo.d.num_components != (td->td_planarconfig == PLANARCONFIG_CONTIG - ? td->td_samplesperpixel - : 1)) { - TIFFErrorExtR(tif, module, "Improper JPEG component count"); - return (0); - } + if (isTiled(tif)) + { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } + else + { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + sp->bytesperline = TIFFScanlineSize(tif); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) + { + /* + * For PC 2, scale down the expected strip/tile size + * to match a downsampled component + */ + segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); + segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); + } + if (sp->cinfo.d.image_width < segment_width || + sp->cinfo.d.image_height < segment_height) + { + TIFFWarningExtR(tif, module, + "Improper JPEG strip/tile size, " + "expected %" PRIu32 "x%" PRIu32 ", got %ux%u", + segment_width, segment_height, sp->cinfo.d.image_width, + sp->cinfo.d.image_height); + } + if (sp->cinfo.d.image_width == segment_width && + sp->cinfo.d.image_height > segment_height && + tif->tif_row + segment_height == td->td_imagelength && !isTiled(tif)) + { + /* Some files have a last strip, that should be truncated, */ + /* but their JPEG codestream has still the maximum strip */ + /* height. Warn about this as this is non compliant, but */ + /* we can safely recover from that. */ + TIFFWarningExtR(tif, module, + "JPEG strip size exceeds expected dimensions," + " expected %" PRIu32 "x%" PRIu32 ", got %ux%u", + segment_width, segment_height, sp->cinfo.d.image_width, + sp->cinfo.d.image_height); + } + else if (sp->cinfo.d.image_width > segment_width || + sp->cinfo.d.image_height > segment_height) + { + /* + * This case could be dangerous, if the strip or tile size has + * been reported as less than the amount of data jpeg will + * return, some potential security issues arise. Catch this + * case and error out. + */ + TIFFErrorExtR(tif, module, + "JPEG strip/tile size exceeds expected dimensions," + " expected %" PRIu32 "x%" PRIu32 ", got %ux%u", + segment_width, segment_height, sp->cinfo.d.image_width, + sp->cinfo.d.image_height); + return (0); + } + if (sp->cinfo.d.num_components != + (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel + : 1)) + { + TIFFErrorExtR(tif, module, "Improper JPEG component count"); + return (0); + } #ifdef JPEG_LIB_MK1 - if (12 != td->td_bitspersample && 8 != td->td_bitspersample) { - TIFFErrorExtR(tif, module, "Improper JPEG data precision"); - return (0); - } - sp->cinfo.d.data_precision = td->td_bitspersample; - sp->cinfo.d.bits_in_jsample = td->td_bitspersample; + if (12 != td->td_bitspersample && 8 != td->td_bitspersample) + { + TIFFErrorExtR(tif, module, "Improper JPEG data precision"); + return (0); + } + sp->cinfo.d.data_precision = td->td_bitspersample; + sp->cinfo.d.bits_in_jsample = td->td_bitspersample; #else - if (sp->cinfo.d.data_precision != td->td_bitspersample) { - TIFFErrorExtR(tif, module, "Improper JPEG data precision"); - return (0); - } + if (sp->cinfo.d.data_precision != td->td_bitspersample) + { + TIFFErrorExtR(tif, module, "Improper JPEG data precision"); + return (0); + } #endif - if (sp->cinfo.d.progressive_mode && - !sp->otherSettings.has_warned_about_progressive_mode) { - TIFFWarningExtR(tif, module, - "The JPEG strip/tile is encoded with progressive mode, " - "which is normally not legal for JPEG-in-TIFF.\n" - "libtiff should be able to decode it, but it might " - "cause compatibility issues with other readers"); - sp->otherSettings.has_warned_about_progressive_mode = TRUE; - } - - /* In some cases, libjpeg needs to allocate a lot of memory */ - /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf - */ - if (TIFFjpeg_has_multiple_scans(sp)) { - /* In this case libjpeg will need to allocate memory or backing */ - /* store for all coefficients */ - /* See call to jinit_d_coef_controller() from master_selection() */ - /* in libjpeg */ - - /* 1 MB for regular libjpeg usage */ - toff_t nRequiredMemory = 1024 * 1024; - - for (ci = 0; ci < sp->cinfo.d.num_components; ci++) { - const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]); - if (compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0) { - nRequiredMemory += - (toff_t)(((compptr->width_in_blocks + compptr->h_samp_factor - 1) / - compptr->h_samp_factor)) * - ((compptr->height_in_blocks + compptr->v_samp_factor - 1) / - compptr->v_samp_factor) * - sizeof(JBLOCK); - } - } - - if (sp->cinfo.d.mem->max_memory_to_use > 0 && - nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) && - getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL) { - TIFFErrorExtR( - tif, module, - "Reading this image would require libjpeg to allocate " - "at least %" PRIu64 " bytes. " - "This is disabled since above the %ld threshold. " - "You may override this restriction by defining the " - "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, " - "or setting the JPEGMEM environment variable to a value greater " - "or equal to '%" PRIu64 "M'", - nRequiredMemory, sp->cinfo.d.mem->max_memory_to_use, - (nRequiredMemory + 1000000u - 1u) / 1000000u); - return 0; - } - } - - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - /* Component 0 should have expected sampling factors */ - if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || - sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) { - TIFFErrorExtR(tif, module, - "Improper JPEG sampling factors %d,%d\n" - "Apparently should be %" PRIu16 ",%" PRIu16 ".", - sp->cinfo.d.comp_info[0].h_samp_factor, - sp->cinfo.d.comp_info[0].v_samp_factor, sp->h_sampling, - sp->v_sampling); - return (0); - } - /* Rest should have sampling factors 1,1 */ - for (ci = 1; ci < sp->cinfo.d.num_components; ci++) { - if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 || - sp->cinfo.d.comp_info[ci].v_samp_factor != 1) { - TIFFErrorExtR(tif, module, - "Improper JPEG sampling factors"); - return (0); - } - } - } else { - /* PC 2's single component should have sampling factors 1,1 */ - if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 || - sp->cinfo.d.comp_info[0].v_samp_factor != 1) { - TIFFErrorExtR(tif, module, - "Improper JPEG sampling factors"); - return (0); - } - } - downsampled_output = FALSE; - if (td->td_planarconfig == PLANARCONFIG_CONTIG && - sp->photometric == PHOTOMETRIC_YCBCR && - sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) { - /* Convert YCbCr to RGB */ - sp->cinfo.d.jpeg_color_space = JCS_YCbCr; - sp->cinfo.d.out_color_space = JCS_RGB; - } else { - /* Suppress colorspace handling */ - sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; - sp->cinfo.d.out_color_space = JCS_UNKNOWN; + if (sp->cinfo.d.progressive_mode && + !sp->otherSettings.has_warned_about_progressive_mode) + { + TIFFWarningExtR(tif, module, + "The JPEG strip/tile is encoded with progressive mode, " + "which is normally not legal for JPEG-in-TIFF.\n" + "libtiff should be able to decode it, but it might " + "cause compatibility issues with other readers"); + sp->otherSettings.has_warned_about_progressive_mode = TRUE; + } + + /* In some cases, libjpeg needs to allocate a lot of memory */ + /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf + */ + if (TIFFjpeg_has_multiple_scans(sp)) + { + /* In this case libjpeg will need to allocate memory or backing */ + /* store for all coefficients */ + /* See call to jinit_d_coef_controller() from master_selection() */ + /* in libjpeg */ + + /* 1 MB for regular libjpeg usage */ + toff_t nRequiredMemory = 1024 * 1024; + + for (ci = 0; ci < sp->cinfo.d.num_components; ci++) + { + const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]); + if (compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0) + { + nRequiredMemory += + (toff_t)(((compptr->width_in_blocks + + compptr->h_samp_factor - 1) / + compptr->h_samp_factor)) * + ((compptr->height_in_blocks + compptr->v_samp_factor - 1) / + compptr->v_samp_factor) * + sizeof(JBLOCK); + } + } + + if (sp->cinfo.d.mem->max_memory_to_use > 0 && + nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) && + getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL) + { + TIFFErrorExtR( + tif, module, + "Reading this image would require libjpeg to allocate " + "at least %" PRIu64 " bytes. " + "This is disabled since above the %ld threshold. " + "You may override this restriction by defining the " + "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, " + "or setting the JPEGMEM environment variable to a value " + "greater " + "or equal to '%" PRIu64 "M'", + nRequiredMemory, sp->cinfo.d.mem->max_memory_to_use, + (nRequiredMemory + 1000000u - 1u) / 1000000u); + return 0; + } + } + + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + /* Component 0 should have expected sampling factors */ + if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling || + sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) + { + TIFFErrorExtR(tif, module, + "Improper JPEG sampling factors %d,%d\n" + "Apparently should be %" PRIu16 ",%" PRIu16 ".", + sp->cinfo.d.comp_info[0].h_samp_factor, + sp->cinfo.d.comp_info[0].v_samp_factor, + sp->h_sampling, sp->v_sampling); + return (0); + } + /* Rest should have sampling factors 1,1 */ + for (ci = 1; ci < sp->cinfo.d.num_components; ci++) + { + if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 || + sp->cinfo.d.comp_info[ci].v_samp_factor != 1) + { + TIFFErrorExtR(tif, module, "Improper JPEG sampling factors"); + return (0); + } + } + } + else + { + /* PC 2's single component should have sampling factors 1,1 */ + if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 || + sp->cinfo.d.comp_info[0].v_samp_factor != 1) + { + TIFFErrorExtR(tif, module, "Improper JPEG sampling factors"); + return (0); + } + } + downsampled_output = FALSE; if (td->td_planarconfig == PLANARCONFIG_CONTIG && - (sp->h_sampling != 1 || sp->v_sampling != 1)) - downsampled_output = TRUE; - /* XXX what about up-sampling? */ - } - if (downsampled_output) { - /* Need to use raw-data interface to libjpeg */ - sp->cinfo.d.raw_data_out = TRUE; + sp->photometric == PHOTOMETRIC_YCBCR && + sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) + { + /* Convert YCbCr to RGB */ + sp->cinfo.d.jpeg_color_space = JCS_YCbCr; + sp->cinfo.d.out_color_space = JCS_RGB; + } + else + { + /* Suppress colorspace handling */ + sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN; + sp->cinfo.d.out_color_space = JCS_UNKNOWN; + if (td->td_planarconfig == PLANARCONFIG_CONTIG && + (sp->h_sampling != 1 || sp->v_sampling != 1)) + downsampled_output = TRUE; + /* XXX what about up-sampling? */ + } + if (downsampled_output) + { + /* Need to use raw-data interface to libjpeg */ + sp->cinfo.d.raw_data_out = TRUE; #if JPEG_LIB_VERSION >= 70 - sp->cinfo.d.do_fancy_upsampling = FALSE; + sp->cinfo.d.do_fancy_upsampling = FALSE; #endif /* JPEG_LIB_VERSION >= 70 */ - tif->tif_decoderow = DecodeRowError; - tif->tif_decodestrip = JPEGDecodeRaw; - tif->tif_decodetile = JPEGDecodeRaw; - } else { - /* Use normal interface to libjpeg */ - sp->cinfo.d.raw_data_out = FALSE; - tif->tif_decoderow = JPEGDecode; - tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; - } - /* Start JPEG decompressor */ - if (!TIFFjpeg_start_decompress(sp)) - return (0); - /* Allocate downsampled-data buffers if needed */ - if (downsampled_output) { - if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info, - sp->cinfo.d.num_components)) - return (0); - sp->scancount = DCTSIZE; /* mark buffer empty */ - } - return (1); + tif->tif_decoderow = DecodeRowError; + tif->tif_decodestrip = JPEGDecodeRaw; + tif->tif_decodetile = JPEGDecodeRaw; + } + else + { + /* Use normal interface to libjpeg */ + sp->cinfo.d.raw_data_out = FALSE; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + } + /* Start JPEG decompressor */ + if (!TIFFjpeg_start_decompress(sp)) + return (0); + /* Allocate downsampled-data buffers if needed */ + if (downsampled_output) + { + if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info, + sp->cinfo.d.num_components)) + return (0); + sp->scancount = DCTSIZE; /* mark buffer empty */ + } + return (1); } /* @@ -1331,149 +1457,163 @@ int TIFFJPEGIsFullStripRequired(TIFF *tif) { * "Standard" case: returned data is not downsampled. */ #if !JPEG_LIB_MK1_OR_12BIT -static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - JPEGState *sp = JState(tif); - tmsize_t nrows; - (void)s; - - /* - ** Update available information, buffer may have been refilled - ** between decode requests - */ - sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp; - sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; - - if (sp->bytesperline == 0) - return 0; +static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) +{ + JPEGState *sp = JState(tif); + tmsize_t nrows; + (void)s; - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExtR(tif, tif->tif_name, - "fractional scanline not read"); + /* + ** Update available information, buffer may have been refilled + ** between decode requests + */ + sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp; + sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; - if (nrows > (tmsize_t)sp->cinfo.d.image_height) - nrows = sp->cinfo.d.image_height; + if (sp->bytesperline == 0) + return 0; - /* data is expected to be read in multiples of a scanline */ - if (nrows) { - do { - /* - * In the libjpeg6b-9a 8bit case. We read directly into - * the TIFF buffer. - */ - JSAMPROW bufptr = (JSAMPROW)buf; + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read"); - if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1) - return (0); + if (nrows > (tmsize_t)sp->cinfo.d.image_height) + nrows = sp->cinfo.d.image_height; - ++tif->tif_row; - buf += sp->bytesperline; - cc -= sp->bytesperline; - } while (--nrows > 0); - } + /* data is expected to be read in multiples of a scanline */ + if (nrows) + { + do + { + /* + * In the libjpeg6b-9a 8bit case. We read directly into + * the TIFF buffer. + */ + JSAMPROW bufptr = (JSAMPROW)buf; + + if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1) + return (0); + + ++tif->tif_row; + buf += sp->bytesperline; + cc -= sp->bytesperline; + } while (--nrows > 0); + } - /* Update information on consumed data */ - tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; + /* Update information on consumed data */ + tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; - /* Close down the decompressor if we've finished the strip or tile. */ - return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || - TIFFjpeg_finish_decompress(sp); + /* Close down the decompressor if we've finished the strip or tile. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || + TIFFjpeg_finish_decompress(sp); } #endif /* !JPEG_LIB_MK1_OR_12BIT */ #if JPEG_LIB_MK1_OR_12BIT /*ARGSUSED*/ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, - uint16_t s) { - JPEGState *sp = JState(tif); - tmsize_t nrows; - (void)s; - - /* - ** Update available information, buffer may have been refilled - ** between decode requests - */ - sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp; - sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; - - if (sp->bytesperline == 0) - return 0; + uint16_t s) +{ + JPEGState *sp = JState(tif); + tmsize_t nrows; + (void)s; - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExtR(tif, tif->tif_name, - "fractional scanline not read"); + /* + ** Update available information, buffer may have been refilled + ** between decode requests + */ + sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp; + sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc; - if (nrows > (tmsize_t)sp->cinfo.d.image_height) - nrows = sp->cinfo.d.image_height; + if (sp->bytesperline == 0) + return 0; - /* data is expected to be read in multiples of a scanline */ - if (nrows) { - TIFF_JSAMPROW line_work_buf = NULL; + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read"); - /* - * For 6B, only use temporary buffer for 12 bit imagery. - * For Mk1 always use it. - */ - if (sp->cinfo.d.data_precision == 12) { - line_work_buf = - (TIFF_JSAMPROW)_TIFFmallocExt( - tif, sizeof(short) * sp->cinfo.d.output_width * - sp->cinfo.d.num_components); - } + if (nrows > (tmsize_t)sp->cinfo.d.image_height) + nrows = sp->cinfo.d.image_height; + + /* data is expected to be read in multiples of a scanline */ + if (nrows) + { + TIFF_JSAMPROW line_work_buf = NULL; - do { - if (line_work_buf != NULL) { /* - * In the MK1 case, we always read into a 16bit - * buffer, and then pack down to 12bit or 8bit. - * In 6B case we only read into 16 bit buffer - * for 12bit data, which we need to repack. + * For 6B, only use temporary buffer for 12 bit imagery. + * For Mk1 always use it. */ - if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) - return (0); - - if (sp->cinfo.d.data_precision == 12) { - int value_pairs = - (sp->cinfo.d.output_width * sp->cinfo.d.num_components) / 2; - int iPair; - - for (iPair = 0; iPair < value_pairs; iPair++) { - unsigned char *out_ptr = ((unsigned char *)buf) + iPair * 3; - TIFF_JSAMPLE *in_ptr = line_work_buf + iPair * 2; - - out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); - out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4) | - ((in_ptr[1] & 0xf00) >> 8)); - out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); - } - } else if (sp->cinfo.d.data_precision == 8) { - int value_count = - (sp->cinfo.d.output_width * sp->cinfo.d.num_components); - int iValue; - - for (iValue = 0; iValue < value_count; iValue++) { - ((unsigned char *)buf)[iValue] = line_work_buf[iValue] & 0xff; - } + if (sp->cinfo.d.data_precision == 12) + { + line_work_buf = (TIFF_JSAMPROW)_TIFFmallocExt( + tif, sizeof(short) * sp->cinfo.d.output_width * + sp->cinfo.d.num_components); } - } - ++tif->tif_row; - buf += sp->bytesperline; - cc -= sp->bytesperline; - } while (--nrows > 0); + do + { + if (line_work_buf != NULL) + { + /* + * In the MK1 case, we always read into a 16bit + * buffer, and then pack down to 12bit or 8bit. + * In 6B case we only read into 16 bit buffer + * for 12bit data, which we need to repack. + */ + if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1) + return (0); + + if (sp->cinfo.d.data_precision == 12) + { + int value_pairs = (sp->cinfo.d.output_width * + sp->cinfo.d.num_components) / + 2; + int iPair; + + for (iPair = 0; iPair < value_pairs; iPair++) + { + unsigned char *out_ptr = + ((unsigned char *)buf) + iPair * 3; + TIFF_JSAMPLE *in_ptr = line_work_buf + iPair * 2; + + out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); + out_ptr[1] = + (unsigned char)(((in_ptr[0] & 0xf) << 4) | + ((in_ptr[1] & 0xf00) >> 8)); + out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); + } + } + else if (sp->cinfo.d.data_precision == 8) + { + int value_count = + (sp->cinfo.d.output_width * sp->cinfo.d.num_components); + int iValue; + + for (iValue = 0; iValue < value_count; iValue++) + { + ((unsigned char *)buf)[iValue] = + line_work_buf[iValue] & 0xff; + } + } + } - if (line_work_buf != NULL) - _TIFFfreeExt(tif, line_work_buf); - } + ++tif->tif_row; + buf += sp->bytesperline; + cc -= sp->bytesperline; + } while (--nrows > 0); - /* Update information on consumed data */ - tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; - tif->tif_rawcc = sp->src.bytes_in_buffer; + if (line_work_buf != NULL) + _TIFFfreeExt(tif, line_work_buf); + } - /* Close down the decompressor if we've finished the strip or tile. */ - return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || - TIFFjpeg_finish_decompress(sp); + /* Update information on consumed data */ + tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte; + tif->tif_rawcc = sp->src.bytes_in_buffer; + + /* Close down the decompressor if we've finished the strip or tile. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || + TIFFjpeg_finish_decompress(sp); } #endif /* JPEG_LIB_MK1_OR_12BIT */ @@ -1481,15 +1621,16 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { uint16_t s) { - (void)buf; - (void)cc; - (void)s; - - TIFFErrorExtR(tif, "TIFFReadScanline", - "scanline oriented access is not supported for downsampled JPEG " - "compressed images, consider enabling TIFFTAG_JPEGCOLORMODE as " - "JPEGCOLORMODE_RGB."); - return 0; + (void)buf; + (void)cc; + (void)s; + + TIFFErrorExtR( + tif, "TIFFReadScanline", + "scanline oriented access is not supported for downsampled JPEG " + "compressed images, consider enabling TIFFTAG_JPEGCOLORMODE as " + "JPEGCOLORMODE_RGB."); + return 0; } /* @@ -1497,218 +1638,252 @@ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { * Returned data is downsampled per sampling factors. */ /*ARGSUSED*/ static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, - uint16_t s) { - JPEGState *sp = JState(tif); - tmsize_t nrows; - TIFFDirectory *td = &tif->tif_dir; - (void)s; - - nrows = sp->cinfo.d.image_height; - /* For last strip, limit number of rows to its truncated height */ - /* even if the codestream height is larger (which is not compliant, */ - /* but that we tolerate) */ - if ((uint32_t)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif)) - nrows = td->td_imagelength - tif->tif_row; + uint16_t s) +{ + JPEGState *sp = JState(tif); + tmsize_t nrows; + TIFFDirectory *td = &tif->tif_dir; + (void)s; + + nrows = sp->cinfo.d.image_height; + /* For last strip, limit number of rows to its truncated height */ + /* even if the codestream height is larger (which is not compliant, */ + /* but that we tolerate) */ + if ((uint32_t)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif)) + nrows = td->td_imagelength - tif->tif_row; #if defined(JPEG_LIB_MK1_OR_12BIT) - unsigned short *tmpbuf = NULL; + unsigned short *tmpbuf = NULL; #endif - /* data is expected to be read in multiples of a scanline */ - if (nrows != 0) { + /* data is expected to be read in multiples of a scanline */ + if (nrows != 0) + { - /* Cb,Cr both have sampling factors 1, so this is correct */ - JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; - int samples_per_clump = sp->samplesperclump; + /* Cb,Cr both have sampling factors 1, so this is correct */ + JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width; + int samples_per_clump = sp->samplesperclump; #if defined(JPEG_LIB_MK1_OR_12BIT) - tmpbuf = _TIFFmallocExt(tif, sizeof(unsigned short) * sp->cinfo.d.output_width * - sp->cinfo.d.num_components); - if (tmpbuf == NULL) { - TIFFErrorExtR(tif, "JPEGDecodeRaw", "Out of memory"); - return 0; - } + tmpbuf = _TIFFmallocExt(tif, sizeof(unsigned short) * + sp->cinfo.d.output_width * + sp->cinfo.d.num_components); + if (tmpbuf == NULL) + { + TIFFErrorExtR(tif, "JPEGDecodeRaw", "Out of memory"); + return 0; + } #endif - do { - jpeg_component_info *compptr; - int ci, clumpoffset; - - if (cc < sp->bytesperline) { - TIFFErrorExtR(tif, "JPEGDecodeRaw", - "application buffer not large enough for all data."); - goto error; - } - - /* Reload downsampled-data buffer if needed */ - if (sp->scancount >= DCTSIZE) { - int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) - goto error; - sp->scancount = 0; - } - /* - * Fastest way to unseparate data is to make one pass - * over the scanline for each row of each component. - */ - clumpoffset = 0; /* first sample in clump */ - for (ci = 0, compptr = sp->cinfo.d.comp_info; - ci < sp->cinfo.d.num_components; ci++, compptr++) { - int hsamp = compptr->h_samp_factor; - int vsamp = compptr->v_samp_factor; - int ypos; - - for (ypos = 0; ypos < vsamp; ypos++) { - TIFF_JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount * vsamp + ypos]; - JDIMENSION nclump; + do + { + jpeg_component_info *compptr; + int ci, clumpoffset; + + if (cc < sp->bytesperline) + { + TIFFErrorExtR( + tif, "JPEGDecodeRaw", + "application buffer not large enough for all data."); + goto error; + } + + /* Reload downsampled-data buffer if needed */ + if (sp->scancount >= DCTSIZE) + { + int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n) + goto error; + sp->scancount = 0; + } + /* + * Fastest way to unseparate data is to make one pass + * over the scanline for each row of each component. + */ + clumpoffset = 0; /* first sample in clump */ + for (ci = 0, compptr = sp->cinfo.d.comp_info; + ci < sp->cinfo.d.num_components; ci++, compptr++) + { + int hsamp = compptr->h_samp_factor; + int vsamp = compptr->v_samp_factor; + int ypos; + + for (ypos = 0; ypos < vsamp; ypos++) + { + TIFF_JSAMPLE *inptr = + sp->ds_buffer[ci][sp->scancount * vsamp + ypos]; + JDIMENSION nclump; #if defined(JPEG_LIB_MK1_OR_12BIT) - TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)tmpbuf + clumpoffset; + TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)tmpbuf + clumpoffset; #else - TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)buf + clumpoffset; - if (cc < - (tmsize_t)(clumpoffset + - (tmsize_t)samples_per_clump * (clumps_per_line - 1) + - hsamp)) { - TIFFErrorExtR(tif, "JPEGDecodeRaw", - "application buffer not large enough for all data, " - "possible subsampling issue"); - goto error; - } + TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)buf + clumpoffset; + if (cc < (tmsize_t)(clumpoffset + + (tmsize_t)samples_per_clump * + (clumps_per_line - 1) + + hsamp)) + { + TIFFErrorExtR( + tif, "JPEGDecodeRaw", + "application buffer not large enough for all data, " + "possible subsampling issue"); + goto error; + } #endif - if (hsamp == 1) { - /* fast path for at least Cb and Cr */ - for (nclump = clumps_per_line; nclump-- > 0;) { - outptr[0] = *inptr++; - outptr += samples_per_clump; + if (hsamp == 1) + { + /* fast path for at least Cb and Cr */ + for (nclump = clumps_per_line; nclump-- > 0;) + { + outptr[0] = *inptr++; + outptr += samples_per_clump; + } + } + else + { + int xpos; + + /* general case */ + for (nclump = clumps_per_line; nclump-- > 0;) + { + for (xpos = 0; xpos < hsamp; xpos++) + outptr[xpos] = *inptr++; + outptr += samples_per_clump; + } + } + clumpoffset += hsamp; + } } - } else { - int xpos; - - /* general case */ - for (nclump = clumps_per_line; nclump-- > 0;) { - for (xpos = 0; xpos < hsamp; xpos++) - outptr[xpos] = *inptr++; - outptr += samples_per_clump; - } - } - clumpoffset += hsamp; - } - } #if defined(JPEG_LIB_MK1_OR_12BIT) - { - if (sp->cinfo.d.data_precision == 8) { - int i = 0; - int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components; - for (i = 0; i < len; i++) { - ((unsigned char *)buf)[i] = tmpbuf[i] & 0xff; - } - } else { /* 12-bit */ - int value_pairs = - (sp->cinfo.d.output_width * sp->cinfo.d.num_components) / 2; - int iPair; - for (iPair = 0; iPair < value_pairs; iPair++) { - unsigned char *out_ptr = ((unsigned char *)buf) + iPair * 3; - JSAMPLE *in_ptr = (JSAMPLE *)(tmpbuf + iPair * 2); - out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); - out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4) | - ((in_ptr[1] & 0xf00) >> 8)); - out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); - } - } - } + { + if (sp->cinfo.d.data_precision == 8) + { + int i = 0; + int len = + sp->cinfo.d.output_width * sp->cinfo.d.num_components; + for (i = 0; i < len; i++) + { + ((unsigned char *)buf)[i] = tmpbuf[i] & 0xff; + } + } + else + { /* 12-bit */ + int value_pairs = (sp->cinfo.d.output_width * + sp->cinfo.d.num_components) / + 2; + int iPair; + for (iPair = 0; iPair < value_pairs; iPair++) + { + unsigned char *out_ptr = + ((unsigned char *)buf) + iPair * 3; + JSAMPLE *in_ptr = (JSAMPLE *)(tmpbuf + iPair * 2); + out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4); + out_ptr[1] = + (unsigned char)(((in_ptr[0] & 0xf) << 4) | + ((in_ptr[1] & 0xf00) >> 8)); + out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0)); + } + } + } #endif - sp->scancount++; - tif->tif_row += sp->v_sampling; + sp->scancount++; + tif->tif_row += sp->v_sampling; - buf += sp->bytesperline; - cc -= sp->bytesperline; + buf += sp->bytesperline; + cc -= sp->bytesperline; - nrows -= sp->v_sampling; - } while (nrows > 0); + nrows -= sp->v_sampling; + } while (nrows > 0); #if defined(JPEG_LIB_MK1_OR_12BIT) - _TIFFfreeExt(tif, tmpbuf); + _TIFFfreeExt(tif, tmpbuf); #endif - } + } - /* Close down the decompressor if done. */ - return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || - TIFFjpeg_finish_decompress(sp); + /* Close down the decompressor if done. */ + return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height || + TIFFjpeg_finish_decompress(sp); error: #if defined(JPEG_LIB_MK1_OR_12BIT) - _TIFFfreeExt(tif, tmpbuf); + _TIFFfreeExt(tif, tmpbuf); #endif - return 0; + return 0; } /* * JPEG Encoding. */ -static void unsuppress_quant_table(JPEGState *sp, int tblno) { - JQUANT_TBL *qtbl; +static void unsuppress_quant_table(JPEGState *sp, int tblno) +{ + JQUANT_TBL *qtbl; - if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) - qtbl->sent_table = FALSE; + if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) + qtbl->sent_table = FALSE; } -static void suppress_quant_table(JPEGState *sp, int tblno) { - JQUANT_TBL *qtbl; +static void suppress_quant_table(JPEGState *sp, int tblno) +{ + JQUANT_TBL *qtbl; - if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) - qtbl->sent_table = TRUE; + if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL) + qtbl->sent_table = TRUE; } -static void unsuppress_huff_table(JPEGState *sp, int tblno) { - JHUFF_TBL *htbl; +static void unsuppress_huff_table(JPEGState *sp, int tblno) +{ + JHUFF_TBL *htbl; - if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = FALSE; - if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = FALSE; + if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = FALSE; + if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = FALSE; } -static void suppress_huff_table(JPEGState *sp, int tblno) { - JHUFF_TBL *htbl; +static void suppress_huff_table(JPEGState *sp, int tblno) +{ + JHUFF_TBL *htbl; - if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = TRUE; - if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) - htbl->sent_table = TRUE; + if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = TRUE; + if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL) + htbl->sent_table = TRUE; } -static int prepare_JPEGTables(TIFF *tif) { - JPEGState *sp = JState(tif); +static int prepare_JPEGTables(TIFF *tif) +{ + JPEGState *sp = JState(tif); - /* Initialize quant tables for current quality setting */ - if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE)) - return (0); - /* Mark only the tables we want for output */ - /* NB: chrominance tables are currently used only with YCbCr */ - if (!TIFFjpeg_suppress_tables(sp, TRUE)) - return (0); - if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT) { - unsuppress_quant_table(sp, 0); - if (sp->photometric == PHOTOMETRIC_YCBCR) - unsuppress_quant_table(sp, 1); - } - if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) { - unsuppress_huff_table(sp, 0); - if (sp->photometric == PHOTOMETRIC_YCBCR) - unsuppress_huff_table(sp, 1); - } - /* Direct libjpeg output into otherSettings.jpegtables */ - if (!TIFFjpeg_tables_dest(sp, tif)) - return (0); - /* Emit tables-only datastream */ - if (!TIFFjpeg_write_tables(sp)) - return (0); + /* Initialize quant tables for current quality setting */ + if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE)) + return (0); + /* Mark only the tables we want for output */ + /* NB: chrominance tables are currently used only with YCbCr */ + if (!TIFFjpeg_suppress_tables(sp, TRUE)) + return (0); + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT) + { + unsuppress_quant_table(sp, 0); + if (sp->photometric == PHOTOMETRIC_YCBCR) + unsuppress_quant_table(sp, 1); + } + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) + { + unsuppress_huff_table(sp, 0); + if (sp->photometric == PHOTOMETRIC_YCBCR) + unsuppress_huff_table(sp, 1); + } + /* Direct libjpeg output into otherSettings.jpegtables */ + if (!TIFFjpeg_tables_dest(sp, tif)) + return (0); + /* Emit tables-only datastream */ + if (!TIFFjpeg_write_tables(sp)) + return (0); - return (1); + return (1); } #if defined(JPEG_LIB_VERSION_MAJOR) && \ @@ -1717,703 +1892,809 @@ static int prepare_JPEGTables(TIFF *tif) { /* This is a modified version of std_huff_tables() from jcparam.c * in libjpeg-9d because it no longer initializes default Huffman * tables in jpeg_set_defaults(). */ -static void TIFF_std_huff_tables(j_compress_ptr cinfo) { - - if (cinfo->dc_huff_tbl_ptrs[0] == NULL) { - (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 0); - } - if (cinfo->ac_huff_tbl_ptrs[0] == NULL) { - (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 0); - } - if (cinfo->dc_huff_tbl_ptrs[1] == NULL) { - (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 1); - } - if (cinfo->ac_huff_tbl_ptrs[1] == NULL) { - (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 1); - } +static void TIFF_std_huff_tables(j_compress_ptr cinfo) +{ + + if (cinfo->dc_huff_tbl_ptrs[0] == NULL) + { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 0); + } + if (cinfo->ac_huff_tbl_ptrs[0] == NULL) + { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 0); + } + if (cinfo->dc_huff_tbl_ptrs[1] == NULL) + { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 1); + } + if (cinfo->ac_huff_tbl_ptrs[1] == NULL) + { + (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 1); + } } #endif -static int JPEGSetupEncode(TIFF *tif) { - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGSetupEncode"; +static int JPEGSetupEncode(TIFF *tif) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGSetupEncode"; #if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12) - if (tif->tif_dir.td_bitspersample == 12) { - /* We pass a pointer to a copy of otherSettings, since */ - /* TIFFReInitJPEG_12() will clear sp */ - JPEGOtherSettings savedOtherSettings = sp->otherSettings; - return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 1); - } + if (tif->tif_dir.td_bitspersample == 12) + { + /* We pass a pointer to a copy of otherSettings, since */ + /* TIFFReInitJPEG_12() will clear sp */ + JPEGOtherSettings savedOtherSettings = sp->otherSettings; + return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 1); + } #endif - JPEGInitializeLibJPEG(tif, FALSE); - - assert(sp != NULL); - assert(!sp->cinfo.comm.is_decompressor); - - sp->photometric = td->td_photometric; - - /* - * Initialize all JPEG parameters to default values. - * Note that jpeg_set_defaults needs legal values for - * in_color_space and input_components. - */ - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - sp->cinfo.c.input_components = td->td_samplesperpixel; - if (sp->photometric == PHOTOMETRIC_YCBCR) { - if (sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) { - sp->cinfo.c.in_color_space = JCS_RGB; - } else { - sp->cinfo.c.in_color_space = JCS_YCbCr; - } - } else { - if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || - td->td_photometric == PHOTOMETRIC_MINISBLACK) && - td->td_samplesperpixel == 1) - sp->cinfo.c.in_color_space = JCS_GRAYSCALE; - else if (td->td_photometric == PHOTOMETRIC_RGB && - td->td_samplesperpixel == 3) - sp->cinfo.c.in_color_space = JCS_RGB; - else if (td->td_photometric == PHOTOMETRIC_SEPARATED && - td->td_samplesperpixel == 4) - sp->cinfo.c.in_color_space = JCS_CMYK; - else + JPEGInitializeLibJPEG(tif, FALSE); + + assert(sp != NULL); + assert(!sp->cinfo.comm.is_decompressor); + + sp->photometric = td->td_photometric; + + /* + * Initialize all JPEG parameters to default values. + * Note that jpeg_set_defaults needs legal values for + * in_color_space and input_components. + */ + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + sp->cinfo.c.input_components = td->td_samplesperpixel; + if (sp->photometric == PHOTOMETRIC_YCBCR) + { + if (sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) + { + sp->cinfo.c.in_color_space = JCS_RGB; + } + else + { + sp->cinfo.c.in_color_space = JCS_YCbCr; + } + } + else + { + if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || + td->td_photometric == PHOTOMETRIC_MINISBLACK) && + td->td_samplesperpixel == 1) + sp->cinfo.c.in_color_space = JCS_GRAYSCALE; + else if (td->td_photometric == PHOTOMETRIC_RGB && + td->td_samplesperpixel == 3) + sp->cinfo.c.in_color_space = JCS_RGB; + else if (td->td_photometric == PHOTOMETRIC_SEPARATED && + td->td_samplesperpixel == 4) + sp->cinfo.c.in_color_space = JCS_CMYK; + else + sp->cinfo.c.in_color_space = JCS_UNKNOWN; + } + } + else + { + sp->cinfo.c.input_components = 1; sp->cinfo.c.in_color_space = JCS_UNKNOWN; } - } else { - sp->cinfo.c.input_components = 1; - sp->cinfo.c.in_color_space = JCS_UNKNOWN; - } - if (!TIFFjpeg_set_defaults(sp)) - return (0); - - /* mozjpeg by default enables progressive JPEG, which is illegal in - * JPEG-in-TIFF */ - /* So explicitly disable it. */ - if (sp->cinfo.c.num_scans != 0 && - (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0) { - /* it has been found that mozjpeg could create corrupt strips/tiles */ - /* in non optimize_coding mode. */ - TIFFWarningExtR(tif, module, - "mozjpeg library likely detected. Disable emission of " - "Huffman tables in JpegTables tag, and use optimize_coding " - "to avoid potential issues"); - sp->otherSettings.jpegtablesmode &= ~JPEGTABLESMODE_HUFF; - } - sp->cinfo.c.num_scans = 0; - sp->cinfo.c.scan_info = NULL; - - /* Set per-file parameters */ - switch (sp->photometric) { - case PHOTOMETRIC_YCBCR: - sp->h_sampling = td->td_ycbcrsubsampling[0]; - sp->v_sampling = td->td_ycbcrsubsampling[1]; - if (sp->h_sampling == 0 || sp->v_sampling == 0) { - TIFFErrorExtR(tif, module, - "Invalig horizontal/vertical sampling value"); - return (0); - } - if (td->td_bitspersample > 16) { - TIFFErrorExtR(tif, module, - "BitsPerSample %" PRIu16 " not allowed for JPEG", - td->td_bitspersample); - return (0); + if (!TIFFjpeg_set_defaults(sp)) + return (0); + + /* mozjpeg by default enables progressive JPEG, which is illegal in + * JPEG-in-TIFF */ + /* So explicitly disable it. */ + if (sp->cinfo.c.num_scans != 0 && + (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0) + { + /* it has been found that mozjpeg could create corrupt strips/tiles */ + /* in non optimize_coding mode. */ + TIFFWarningExtR( + tif, module, + "mozjpeg library likely detected. Disable emission of " + "Huffman tables in JpegTables tag, and use optimize_coding " + "to avoid potential issues"); + sp->otherSettings.jpegtablesmode &= ~JPEGTABLESMODE_HUFF; } + sp->cinfo.c.num_scans = 0; + sp->cinfo.c.scan_info = NULL; - /* - * A ReferenceBlackWhite field *must* be present since the - * default value is inappropriate for YCbCr. Fill in the - * proper value if application didn't set it. - */ + /* Set per-file parameters */ + switch (sp->photometric) { - float *ref; - if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref)) { - float refbw[6]; - long top = 1L << td->td_bitspersample; - refbw[0] = 0; - refbw[1] = (float)(top - 1L); - refbw[2] = (float)(top >> 1); - refbw[3] = refbw[1]; - refbw[4] = refbw[2]; - refbw[5] = refbw[1]; - TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw); - } - } - break; - case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ - case PHOTOMETRIC_MASK: - TIFFErrorExtR(tif, module, - "PhotometricInterpretation %" PRIu16 " not allowed for JPEG", - sp->photometric); - return (0); - default: - /* TIFF 6.0 forbids subsampling of all other color spaces */ - sp->h_sampling = 1; - sp->v_sampling = 1; - break; - } - - /* Verify miscellaneous parameters */ - - /* - * This would need work if libtiff ever supports different - * depths for different components, or if libjpeg ever supports - * run-time selection of depth. Neither is imminent. - */ + case PHOTOMETRIC_YCBCR: + sp->h_sampling = td->td_ycbcrsubsampling[0]; + sp->v_sampling = td->td_ycbcrsubsampling[1]; + if (sp->h_sampling == 0 || sp->v_sampling == 0) + { + TIFFErrorExtR(tif, module, + "Invalig horizontal/vertical sampling value"); + return (0); + } + if (td->td_bitspersample > 16) + { + TIFFErrorExtR(tif, module, + "BitsPerSample %" PRIu16 " not allowed for JPEG", + td->td_bitspersample); + return (0); + } + + /* + * A ReferenceBlackWhite field *must* be present since the + * default value is inappropriate for YCbCr. Fill in the + * proper value if application didn't set it. + */ + { + float *ref; + if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref)) + { + float refbw[6]; + long top = 1L << td->td_bitspersample; + refbw[0] = 0; + refbw[1] = (float)(top - 1L); + refbw[2] = (float)(top >> 1); + refbw[3] = refbw[1]; + refbw[4] = refbw[2]; + refbw[5] = refbw[1]; + TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw); + } + } + break; + case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */ + case PHOTOMETRIC_MASK: + TIFFErrorExtR(tif, module, + "PhotometricInterpretation %" PRIu16 + " not allowed for JPEG", + sp->photometric); + return (0); + default: + /* TIFF 6.0 forbids subsampling of all other color spaces */ + sp->h_sampling = 1; + sp->v_sampling = 1; + break; + } + + /* Verify miscellaneous parameters */ + + /* + * This would need work if libtiff ever supports different + * depths for different components, or if libjpeg ever supports + * run-time selection of depth. Neither is imminent. + */ #ifdef JPEG_LIB_MK1 - /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */ - if (td->td_bitspersample != 8 && td->td_bitspersample != 12) + /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */ + if (td->td_bitspersample != 8 && td->td_bitspersample != 12) #else - if (td->td_bitspersample != BITS_IN_JSAMPLE) + if (td->td_bitspersample != BITS_IN_JSAMPLE) #endif - { - TIFFErrorExtR(tif, module, - "BitsPerSample %" PRIu16 " not allowed for JPEG", - td->td_bitspersample); - return (0); - } - sp->cinfo.c.data_precision = td->td_bitspersample; + { + TIFFErrorExtR(tif, module, + "BitsPerSample %" PRIu16 " not allowed for JPEG", + td->td_bitspersample); + return (0); + } + sp->cinfo.c.data_precision = td->td_bitspersample; #ifdef JPEG_LIB_MK1 - sp->cinfo.c.bits_in_jsample = td->td_bitspersample; + sp->cinfo.c.bits_in_jsample = td->td_bitspersample; #endif - if (isTiled(tif)) { - if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) { - TIFFErrorExtR(tif, module, - "JPEG tile height must be multiple of %" PRIu32, - (uint32_t)(sp->v_sampling * DCTSIZE)); - return (0); - } - if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) { - TIFFErrorExtR(tif, module, - "JPEG tile width must be multiple of %" PRIu32, - (uint32_t)(sp->h_sampling * DCTSIZE)); - return (0); - } - } else { - if (td->td_rowsperstrip < td->td_imagelength && - (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) { - TIFFErrorExtR(tif, module, - "RowsPerStrip must be multiple of %" PRIu32 " for JPEG", - (uint32_t)(sp->v_sampling * DCTSIZE)); - return (0); - } - } - - /* Create a JPEGTables field if appropriate */ - if (sp->otherSettings.jpegtablesmode & - (JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF)) { - if (sp->otherSettings.jpegtables == NULL || - memcmp(sp->otherSettings.jpegtables, "\0\0\0\0\0\0\0\0\0", 8) == 0) { + if (isTiled(tif)) + { + if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) + { + TIFFErrorExtR(tif, module, + "JPEG tile height must be multiple of %" PRIu32, + (uint32_t)(sp->v_sampling * DCTSIZE)); + return (0); + } + if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) + { + TIFFErrorExtR(tif, module, + "JPEG tile width must be multiple of %" PRIu32, + (uint32_t)(sp->h_sampling * DCTSIZE)); + return (0); + } + } + else + { + if (td->td_rowsperstrip < td->td_imagelength && + (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) + { + TIFFErrorExtR(tif, module, + "RowsPerStrip must be multiple of %" PRIu32 + " for JPEG", + (uint32_t)(sp->v_sampling * DCTSIZE)); + return (0); + } + } + + /* Create a JPEGTables field if appropriate */ + if (sp->otherSettings.jpegtablesmode & + (JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF)) + { + if (sp->otherSettings.jpegtables == NULL || + memcmp(sp->otherSettings.jpegtables, "\0\0\0\0\0\0\0\0\0", 8) == 0) + { #if defined(JPEG_LIB_VERSION_MAJOR) && \ (JPEG_LIB_VERSION_MAJOR > 9 || \ (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4)) - if ((sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0 && - (sp->cinfo.c.dc_huff_tbl_ptrs[0] == NULL || - sp->cinfo.c.dc_huff_tbl_ptrs[1] == NULL || - sp->cinfo.c.ac_huff_tbl_ptrs[0] == NULL || - sp->cinfo.c.ac_huff_tbl_ptrs[1] == NULL)) { - /* libjpeg-9d no longer initializes default Huffman tables in */ - /* jpeg_set_defaults() */ - TIFF_std_huff_tables(&sp->cinfo.c); - } + if ((sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0 && + (sp->cinfo.c.dc_huff_tbl_ptrs[0] == NULL || + sp->cinfo.c.dc_huff_tbl_ptrs[1] == NULL || + sp->cinfo.c.ac_huff_tbl_ptrs[0] == NULL || + sp->cinfo.c.ac_huff_tbl_ptrs[1] == NULL)) + { + /* libjpeg-9d no longer initializes default Huffman tables in */ + /* jpeg_set_defaults() */ + TIFF_std_huff_tables(&sp->cinfo.c); + } #endif - if (!prepare_JPEGTables(tif)) - return (0); - /* Mark the field present */ - /* Can't use TIFFSetField since BEENWRITING is already set! */ - tif->tif_flags |= TIFF_DIRTYDIRECT; - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + if (!prepare_JPEGTables(tif)) + return (0); + /* Mark the field present */ + /* Can't use TIFFSetField since BEENWRITING is already set! */ + tif->tif_flags |= TIFF_DIRTYDIRECT; + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + } + } + else + { + /* We do not support application-supplied JPEGTables, */ + /* so mark the field not present */ + TIFFClrFieldBit(tif, FIELD_JPEGTABLES); } - } else { - /* We do not support application-supplied JPEGTables, */ - /* so mark the field not present */ - TIFFClrFieldBit(tif, FIELD_JPEGTABLES); - } - /* Direct libjpeg output to libtiff's output buffer */ - TIFFjpeg_data_dest(sp, tif); + /* Direct libjpeg output to libtiff's output buffer */ + TIFFjpeg_data_dest(sp, tif); - return (1); + return (1); } /* * Set encoding state at the start of a strip or tile. */ -static int JPEGPreEncode(TIFF *tif, uint16_t s) { - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - static const char module[] = "JPEGPreEncode"; - uint32_t segment_width, segment_height; - int downsampled_input; - - assert(sp != NULL); - - if (sp->cinfo.comm.is_decompressor == 1) { - tif->tif_setupencode(tif); - } - - assert(!sp->cinfo.comm.is_decompressor); - /* - * Set encoding parameters for this strip/tile. - */ - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - sp->bytesperline = TIFFTileRowSize(tif); - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - sp->bytesperline = TIFFScanlineSize(tif); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) { - /* for PC 2, scale down the strip/tile size - * to match a downsampled component +static int JPEGPreEncode(TIFF *tif, uint16_t s) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; + static const char module[] = "JPEGPreEncode"; + uint32_t segment_width, segment_height; + int downsampled_input; + + assert(sp != NULL); + + if (sp->cinfo.comm.is_decompressor == 1) + { + tif->tif_setupencode(tif); + } + + assert(!sp->cinfo.comm.is_decompressor); + /* + * Set encoding parameters for this strip/tile. + */ + if (isTiled(tif)) + { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + sp->bytesperline = TIFFTileRowSize(tif); + } + else + { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + sp->bytesperline = TIFFScanlineSize(tif); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) + { + /* for PC 2, scale down the strip/tile size + * to match a downsampled component + */ + segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); + segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); + } + if (segment_width > 65535 || segment_height > 65535) + { + TIFFErrorExtR(tif, module, "Strip/tile too large for JPEG"); + return (0); + } + sp->cinfo.c.image_width = segment_width; + sp->cinfo.c.image_height = segment_height; + downsampled_input = FALSE; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + sp->cinfo.c.input_components = td->td_samplesperpixel; + if (sp->photometric == PHOTOMETRIC_YCBCR) + { + if (sp->otherSettings.jpegcolormode != JPEGCOLORMODE_RGB) + { + if (sp->h_sampling != 1 || sp->v_sampling != 1) + downsampled_input = TRUE; + } + if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) + return (0); + /* + * Set Y sampling factors; + * we assume jpeg_set_colorspace() set the rest to 1 + */ + sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; + sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; + } + else + { + if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space)) + return (0); + /* jpeg_set_colorspace set all sampling factors to 1 */ + } + } + else + { + if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) + return (0); + sp->cinfo.c.comp_info[0].component_id = s; + /* jpeg_set_colorspace() set sampling factors to 1 */ + if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) + { + sp->cinfo.c.comp_info[0].quant_tbl_no = 1; + sp->cinfo.c.comp_info[0].dc_tbl_no = 1; + sp->cinfo.c.comp_info[0].ac_tbl_no = 1; + } + } + /* ensure libjpeg won't write any extraneous markers */ + sp->cinfo.c.write_JFIF_header = FALSE; + sp->cinfo.c.write_Adobe_marker = FALSE; + /* set up table handling correctly */ + /* calling TIFFjpeg_set_quality() causes quantization tables to be flagged + */ + /* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT */ - segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); - segment_height = TIFFhowmany_32(segment_height, sp->v_sampling); - } - if (segment_width > 65535 || segment_height > 65535) { - TIFFErrorExtR(tif, module, "Strip/tile too large for JPEG"); - return (0); - } - sp->cinfo.c.image_width = segment_width; - sp->cinfo.c.image_height = segment_height; - downsampled_input = FALSE; - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - sp->cinfo.c.input_components = td->td_samplesperpixel; - if (sp->photometric == PHOTOMETRIC_YCBCR) { - if (sp->otherSettings.jpegcolormode != JPEGCOLORMODE_RGB) { - if (sp->h_sampling != 1 || sp->v_sampling != 1) - downsampled_input = TRUE; - } - if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr)) + /* mode, so we must manually suppress them. However TIFFjpeg_set_quality() + */ + /* should really be called when dealing with files with directories with */ + /* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */ + if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE)) return (0); - /* - * Set Y sampling factors; - * we assume jpeg_set_colorspace() set the rest to 1 - */ - sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling; - sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling; - } else { - if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space)) + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT) + { + suppress_quant_table(sp, 0); + suppress_quant_table(sp, 1); + } + else + { + unsuppress_quant_table(sp, 0); + unsuppress_quant_table(sp, 1); + } + if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) + { + /* Explicit suppression is only needed if we did not go through the */ + /* prepare_JPEGTables() code path, which may be the case if updating */ + /* an existing file */ + suppress_huff_table(sp, 0); + suppress_huff_table(sp, 1); + sp->cinfo.c.optimize_coding = FALSE; + } + else + sp->cinfo.c.optimize_coding = TRUE; + if (downsampled_input) + { + /* Need to use raw-data interface to libjpeg */ + sp->cinfo.c.raw_data_in = TRUE; + tif->tif_encoderow = JPEGEncodeRaw; + tif->tif_encodestrip = JPEGEncodeRaw; + tif->tif_encodetile = JPEGEncodeRaw; + } + else + { + /* Use normal interface to libjpeg */ + sp->cinfo.c.raw_data_in = FALSE; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + } + /* Start JPEG compressor */ + if (!TIFFjpeg_start_compress(sp, FALSE)) return (0); - /* jpeg_set_colorspace set all sampling factors to 1 */ - } - } else { - if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN)) - return (0); - sp->cinfo.c.comp_info[0].component_id = s; - /* jpeg_set_colorspace() set sampling factors to 1 */ - if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) { - sp->cinfo.c.comp_info[0].quant_tbl_no = 1; - sp->cinfo.c.comp_info[0].dc_tbl_no = 1; - sp->cinfo.c.comp_info[0].ac_tbl_no = 1; - } - } - /* ensure libjpeg won't write any extraneous markers */ - sp->cinfo.c.write_JFIF_header = FALSE; - sp->cinfo.c.write_Adobe_marker = FALSE; - /* set up table handling correctly */ - /* calling TIFFjpeg_set_quality() causes quantization tables to be flagged */ - /* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT */ - /* mode, so we must manually suppress them. However TIFFjpeg_set_quality() */ - /* should really be called when dealing with files with directories with */ - /* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */ - if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE)) - return (0); - if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT) { - suppress_quant_table(sp, 0); - suppress_quant_table(sp, 1); - } else { - unsuppress_quant_table(sp, 0); - unsuppress_quant_table(sp, 1); - } - if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) { - /* Explicit suppression is only needed if we did not go through the */ - /* prepare_JPEGTables() code path, which may be the case if updating */ - /* an existing file */ - suppress_huff_table(sp, 0); - suppress_huff_table(sp, 1); - sp->cinfo.c.optimize_coding = FALSE; - } else - sp->cinfo.c.optimize_coding = TRUE; - if (downsampled_input) { - /* Need to use raw-data interface to libjpeg */ - sp->cinfo.c.raw_data_in = TRUE; - tif->tif_encoderow = JPEGEncodeRaw; - tif->tif_encodestrip = JPEGEncodeRaw; - tif->tif_encodetile = JPEGEncodeRaw; - } else { - /* Use normal interface to libjpeg */ - sp->cinfo.c.raw_data_in = FALSE; - tif->tif_encoderow = JPEGEncode; - tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; - } - /* Start JPEG compressor */ - if (!TIFFjpeg_start_compress(sp, FALSE)) - return (0); - /* Allocate downsampled-data buffers if needed */ - if (downsampled_input) { - if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, - sp->cinfo.c.num_components)) - return (0); - } - sp->scancount = 0; + /* Allocate downsampled-data buffers if needed */ + if (downsampled_input) + { + if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info, + sp->cinfo.c.num_components)) + return (0); + } + sp->scancount = 0; - return (1); + return (1); } /* * Encode a chunk of pixels. * "Standard" case: incoming data is not downsampled. */ -static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - JPEGState *sp = JState(tif); - tmsize_t nrows; - TIFF_JSAMPROW bufptr[1]; - short *line16 = NULL; - int line16_count = 0; - - (void)s; - assert(sp != NULL); - /* data is expected to be supplied in multiples of a scanline */ - nrows = cc / sp->bytesperline; - if (cc % sp->bytesperline) - TIFFWarningExtR(tif, tif->tif_name, - "fractional scanline discarded"); - - /* The last strip will be limited to image size */ - if (!isTiled(tif) && tif->tif_row + nrows > tif->tif_dir.td_imagelength) - nrows = tif->tif_dir.td_imagelength - tif->tif_row; - - if (sp->cinfo.c.data_precision == 12) { - line16_count = (int)((sp->bytesperline * 2) / 3); - line16 = (short *)_TIFFmallocExt(tif, sizeof(short) * line16_count); - if (!line16) { - TIFFErrorExtR(tif, "JPEGEncode", - "Failed to allocate memory"); +static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) +{ + JPEGState *sp = JState(tif); + tmsize_t nrows; + TIFF_JSAMPROW bufptr[1]; + short *line16 = NULL; + int line16_count = 0; + + (void)s; + assert(sp != NULL); + /* data is expected to be supplied in multiples of a scanline */ + nrows = cc / sp->bytesperline; + if (cc % sp->bytesperline) + TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded"); + + /* The last strip will be limited to image size */ + if (!isTiled(tif) && tif->tif_row + nrows > tif->tif_dir.td_imagelength) + nrows = tif->tif_dir.td_imagelength - tif->tif_row; + + if (sp->cinfo.c.data_precision == 12) + { + line16_count = (int)((sp->bytesperline * 2) / 3); + line16 = (short *)_TIFFmallocExt(tif, sizeof(short) * line16_count); + if (!line16) + { + TIFFErrorExtR(tif, "JPEGEncode", "Failed to allocate memory"); - return 0; + return 0; + } } - } - while (nrows-- > 0) { + while (nrows-- > 0) + { - if (sp->cinfo.c.data_precision == 12) { + if (sp->cinfo.c.data_precision == 12) + { - int value_pairs = line16_count / 2; - int iPair; + int value_pairs = line16_count / 2; + int iPair; - bufptr[0] = (TIFF_JSAMPROW)line16; + bufptr[0] = (TIFF_JSAMPROW)line16; - for (iPair = 0; iPair < value_pairs; iPair++) { - unsigned char *in_ptr = ((unsigned char *)buf) + iPair * 3; - TIFF_JSAMPLE *out_ptr = (TIFF_JSAMPLE *)(line16 + iPair * 2); + for (iPair = 0; iPair < value_pairs; iPair++) + { + unsigned char *in_ptr = ((unsigned char *)buf) + iPair * 3; + TIFF_JSAMPLE *out_ptr = (TIFF_JSAMPLE *)(line16 + iPair * 2); - out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4); - out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2]; - } - } else { - bufptr[0] = (TIFF_JSAMPROW)buf; + out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4); + out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2]; + } + } + else + { + bufptr[0] = (TIFF_JSAMPROW)buf; + } + if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) + return (0); + if (nrows > 0) + tif->tif_row++; + buf += sp->bytesperline; } - if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1) - return (0); - if (nrows > 0) - tif->tif_row++; - buf += sp->bytesperline; - } - if (sp->cinfo.c.data_precision == 12) { - _TIFFfreeExt(tif, line16); - } + if (sp->cinfo.c.data_precision == 12) + { + _TIFFfreeExt(tif, line16); + } - return (1); + return (1); } /* * Encode a chunk of pixels. * Incoming data is expected to be downsampled per sampling factors. */ -static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - JPEGState *sp = JState(tif); - TIFF_JSAMPLE *inptr; - TIFF_JSAMPLE *outptr; - tmsize_t nrows; - JDIMENSION clumps_per_line, nclump; - int clumpoffset, ci, xpos, ypos; - jpeg_component_info *compptr; - int samples_per_clump = sp->samplesperclump; - tmsize_t bytesperclumpline; - - (void)s; - assert(sp != NULL); - /* data is expected to be supplied in multiples of a clumpline */ - /* a clumpline is equivalent to v_sampling desubsampled scanlines */ - /* TODO: the following calculation of bytesperclumpline, should substitute - * calculation of sp->bytesperline, except that it is per v_sampling lines */ - bytesperclumpline = - ((((tmsize_t)sp->cinfo.c.image_width + sp->h_sampling - 1) / - sp->h_sampling) * - ((tmsize_t)sp->h_sampling * sp->v_sampling + 2) * - sp->cinfo.c.data_precision + - 7) / - 8; - - nrows = (cc / bytesperclumpline) * sp->v_sampling; - if (cc % bytesperclumpline) - TIFFWarningExtR(tif, tif->tif_name, - "fractional scanline discarded"); - - /* Cb,Cr both have sampling factors 1, so this is correct */ - clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; - - while (nrows > 0) { - /* - * Fastest way to separate the data is to make one pass - * over the scanline for each row of each component. +static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) +{ + JPEGState *sp = JState(tif); + TIFF_JSAMPLE *inptr; + TIFF_JSAMPLE *outptr; + tmsize_t nrows; + JDIMENSION clumps_per_line, nclump; + int clumpoffset, ci, xpos, ypos; + jpeg_component_info *compptr; + int samples_per_clump = sp->samplesperclump; + tmsize_t bytesperclumpline; + + (void)s; + assert(sp != NULL); + /* data is expected to be supplied in multiples of a clumpline */ + /* a clumpline is equivalent to v_sampling desubsampled scanlines */ + /* TODO: the following calculation of bytesperclumpline, should substitute + * calculation of sp->bytesperline, except that it is per v_sampling lines */ - clumpoffset = 0; /* first sample in clump */ - for (ci = 0, compptr = sp->cinfo.c.comp_info; - ci < sp->cinfo.c.num_components; ci++, compptr++) { - int hsamp = compptr->h_samp_factor; - int vsamp = compptr->v_samp_factor; - int padding = - (int)(compptr->width_in_blocks * DCTSIZE - clumps_per_line * hsamp); - for (ypos = 0; ypos < vsamp; ypos++) { - inptr = ((TIFF_JSAMPLE *)buf) + clumpoffset; - outptr = sp->ds_buffer[ci][sp->scancount * vsamp + ypos]; - if (hsamp == 1) { - /* fast path for at least Cb and Cr */ - for (nclump = clumps_per_line; nclump-- > 0;) { - *outptr++ = inptr[0]; - inptr += samples_per_clump; - } - } else { - /* general case */ - for (nclump = clumps_per_line; nclump-- > 0;) { - for (xpos = 0; xpos < hsamp; xpos++) - *outptr++ = inptr[xpos]; - inptr += samples_per_clump; - } + bytesperclumpline = + ((((tmsize_t)sp->cinfo.c.image_width + sp->h_sampling - 1) / + sp->h_sampling) * + ((tmsize_t)sp->h_sampling * sp->v_sampling + 2) * + sp->cinfo.c.data_precision + + 7) / + 8; + + nrows = (cc / bytesperclumpline) * sp->v_sampling; + if (cc % bytesperclumpline) + TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded"); + + /* Cb,Cr both have sampling factors 1, so this is correct */ + clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width; + + while (nrows > 0) + { + /* + * Fastest way to separate the data is to make one pass + * over the scanline for each row of each component. + */ + clumpoffset = 0; /* first sample in clump */ + for (ci = 0, compptr = sp->cinfo.c.comp_info; + ci < sp->cinfo.c.num_components; ci++, compptr++) + { + int hsamp = compptr->h_samp_factor; + int vsamp = compptr->v_samp_factor; + int padding = (int)(compptr->width_in_blocks * DCTSIZE - + clumps_per_line * hsamp); + for (ypos = 0; ypos < vsamp; ypos++) + { + inptr = ((TIFF_JSAMPLE *)buf) + clumpoffset; + outptr = sp->ds_buffer[ci][sp->scancount * vsamp + ypos]; + if (hsamp == 1) + { + /* fast path for at least Cb and Cr */ + for (nclump = clumps_per_line; nclump-- > 0;) + { + *outptr++ = inptr[0]; + inptr += samples_per_clump; + } + } + else + { + /* general case */ + for (nclump = clumps_per_line; nclump-- > 0;) + { + for (xpos = 0; xpos < hsamp; xpos++) + *outptr++ = inptr[xpos]; + inptr += samples_per_clump; + } + } + /* pad each scanline as needed */ + for (xpos = 0; xpos < padding; xpos++) + { + *outptr = outptr[-1]; + outptr++; + } + clumpoffset += hsamp; + } } - /* pad each scanline as needed */ - for (xpos = 0; xpos < padding; xpos++) { - *outptr = outptr[-1]; - outptr++; + sp->scancount++; + if (sp->scancount >= DCTSIZE) + { + int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + sp->scancount = 0; } - clumpoffset += hsamp; - } + tif->tif_row += sp->v_sampling; + buf += bytesperclumpline; + nrows -= sp->v_sampling; } - sp->scancount++; - if (sp->scancount >= DCTSIZE) { - int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) - return (0); - sp->scancount = 0; - } - tif->tif_row += sp->v_sampling; - buf += bytesperclumpline; - nrows -= sp->v_sampling; - } - return (1); + return (1); } /* * Finish up at the end of a strip or tile. */ -static int JPEGPostEncode(TIFF *tif) { - JPEGState *sp = JState(tif); +static int JPEGPostEncode(TIFF *tif) +{ + JPEGState *sp = JState(tif); + + if (sp->scancount > 0) + { + /* + * Need to emit a partial bufferload of downsampled data. + * Pad the data vertically. + */ + int ci, ypos, n; + jpeg_component_info *compptr; + + for (ci = 0, compptr = sp->cinfo.c.comp_info; + ci < sp->cinfo.c.num_components; ci++, compptr++) + { + int vsamp = compptr->v_samp_factor; + tmsize_t row_width = + compptr->width_in_blocks * DCTSIZE * sizeof(JSAMPLE); + for (ypos = sp->scancount * vsamp; ypos < DCTSIZE * vsamp; ypos++) + { + _TIFFmemcpy((void *)sp->ds_buffer[ci][ypos], + (void *)sp->ds_buffer[ci][ypos - 1], row_width); + } + } + n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; + if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) + return (0); + } + + return (TIFFjpeg_finish_compress(JState(tif))); +} + +static void JPEGCleanup(TIFF *tif) +{ + JPEGState *sp = JState(tif); + + assert(sp != 0); + + tif->tif_tagmethods.vgetfield = sp->otherSettings.vgetparent; + tif->tif_tagmethods.vsetfield = sp->otherSettings.vsetparent; + tif->tif_tagmethods.printdir = sp->otherSettings.printdir; + if (sp->cinfo_initialized) + TIFFjpeg_destroy(sp); /* release libjpeg resources */ + if (sp->otherSettings.jpegtables) /* tag value */ + _TIFFfreeExt(tif, sp->otherSettings.jpegtables); + _TIFFfreeExt(tif, tif->tif_data); /* release local state */ + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); +} + +static void JPEGResetUpsampled(TIFF *tif) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; - if (sp->scancount > 0) { /* - * Need to emit a partial bufferload of downsampled data. - * Pad the data vertically. + * Mark whether returned data is up-sampled or not so TIFFStripSize + * and TIFFTileSize return values that reflect the true amount of + * data. */ - int ci, ypos, n; - jpeg_component_info *compptr; - - for (ci = 0, compptr = sp->cinfo.c.comp_info; - ci < sp->cinfo.c.num_components; ci++, compptr++) { - int vsamp = compptr->v_samp_factor; - tmsize_t row_width = compptr->width_in_blocks * DCTSIZE * sizeof(JSAMPLE); - for (ypos = sp->scancount * vsamp; ypos < DCTSIZE * vsamp; ypos++) { - _TIFFmemcpy((void *)sp->ds_buffer[ci][ypos], - (void *)sp->ds_buffer[ci][ypos - 1], row_width); - } - } - n = sp->cinfo.c.max_v_samp_factor * DCTSIZE; - if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n) - return (0); - } - - return (TIFFjpeg_finish_compress(JState(tif))); -} - -static void JPEGCleanup(TIFF *tif) { - JPEGState *sp = JState(tif); - - assert(sp != 0); - - tif->tif_tagmethods.vgetfield = sp->otherSettings.vgetparent; - tif->tif_tagmethods.vsetfield = sp->otherSettings.vsetparent; - tif->tif_tagmethods.printdir = sp->otherSettings.printdir; - if (sp->cinfo_initialized) - TIFFjpeg_destroy(sp); /* release libjpeg resources */ - if (sp->otherSettings.jpegtables) /* tag value */ - _TIFFfreeExt(tif, sp->otherSettings.jpegtables); - _TIFFfreeExt(tif, tif->tif_data); /* release local state */ - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); -} - -static void JPEGResetUpsampled(TIFF *tif) { - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; - - /* - * Mark whether returned data is up-sampled or not so TIFFStripSize - * and TIFFTileSize return values that reflect the true amount of - * data. - */ - tif->tif_flags &= ~TIFF_UPSAMPLED; - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - if (td->td_photometric == PHOTOMETRIC_YCBCR && - sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) { - tif->tif_flags |= TIFF_UPSAMPLED; - } else { + tif->tif_flags &= ~TIFF_UPSAMPLED; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + if (td->td_photometric == PHOTOMETRIC_YCBCR && + sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB) + { + tif->tif_flags |= TIFF_UPSAMPLED; + } + else + { #ifdef notdef - if (td->td_ycbcrsubsampling[0] != 1 || td->td_ycbcrsubsampling[1] != 1) - ; /* XXX what about up-sampling? */ + if (td->td_ycbcrsubsampling[0] != 1 || + td->td_ycbcrsubsampling[1] != 1) + ; /* XXX what about up-sampling? */ #endif + } + } + + /* + * Must recalculate cached tile size in case sampling state changed. + * Should we really be doing this now if image size isn't set? + */ + if (tif->tif_tilesize > 0) + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); + if (tif->tif_scanlinesize > 0) + tif->tif_scanlinesize = TIFFScanlineSize(tif); +} + +static int JPEGVSetField(TIFF *tif, uint32_t tag, va_list ap) +{ + JPEGState *sp = JState(tif); + const TIFFField *fip; + uint32_t v32; + + assert(sp != NULL); + + switch (tag) + { + case TIFFTAG_JPEGTABLES: + v32 = (uint32_t)va_arg(ap, uint32_t); + if (v32 == 0) + { + /* XXX */ + return (0); + } + _TIFFsetByteArrayExt(tif, &sp->otherSettings.jpegtables, + va_arg(ap, void *), v32); + sp->otherSettings.jpegtables_length = v32; + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + break; + case TIFFTAG_JPEGQUALITY: + sp->otherSettings.jpegquality = (int)va_arg(ap, int); + return (1); /* pseudo tag */ + case TIFFTAG_JPEGCOLORMODE: + sp->otherSettings.jpegcolormode = (int)va_arg(ap, int); + JPEGResetUpsampled(tif); + return (1); /* pseudo tag */ + case TIFFTAG_PHOTOMETRIC: + { + int ret_value = (*sp->otherSettings.vsetparent)(tif, tag, ap); + JPEGResetUpsampled(tif); + return ret_value; + } + case TIFFTAG_JPEGTABLESMODE: + sp->otherSettings.jpegtablesmode = (int)va_arg(ap, int); + return (1); /* pseudo tag */ + case TIFFTAG_YCBCRSUBSAMPLING: + /* mark the fact that we have a real ycbcrsubsampling! */ + sp->otherSettings.ycbcrsampling_fetched = 1; + /* should we be recomputing upsampling info here? */ + return (*sp->otherSettings.vsetparent)(tif, tag, ap); + default: + return (*sp->otherSettings.vsetparent)(tif, tag, ap); + } + + if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) + { + TIFFSetFieldBit(tif, fip->field_bit); + } + else + { + return (0); + } + + tif->tif_flags |= TIFF_DIRTYDIRECT; + return (1); +} + +static int JPEGVGetField(TIFF *tif, uint32_t tag, va_list ap) +{ + JPEGState *sp = JState(tif); + + assert(sp != NULL); + + switch (tag) + { + case TIFFTAG_JPEGTABLES: + *va_arg(ap, uint32_t *) = sp->otherSettings.jpegtables_length; + *va_arg(ap, const void **) = sp->otherSettings.jpegtables; + break; + case TIFFTAG_JPEGQUALITY: + *va_arg(ap, int *) = sp->otherSettings.jpegquality; + break; + case TIFFTAG_JPEGCOLORMODE: + *va_arg(ap, int *) = sp->otherSettings.jpegcolormode; + break; + case TIFFTAG_JPEGTABLESMODE: + *va_arg(ap, int *) = sp->otherSettings.jpegtablesmode; + break; + default: + return (*sp->otherSettings.vgetparent)(tif, tag, ap); + } + return (1); +} + +static void JPEGPrintDir(TIFF *tif, FILE *fd, long flags) +{ + JPEGState *sp = JState(tif); + + assert(sp != NULL); + (void)flags; + + if (sp != NULL) + { + if (TIFFFieldSet(tif, FIELD_JPEGTABLES)) + fprintf(fd, " JPEG Tables: (%" PRIu32 " bytes)\n", + sp->otherSettings.jpegtables_length); + if (sp->otherSettings.printdir) + (*sp->otherSettings.printdir)(tif, fd, flags); } - } - - /* - * Must recalculate cached tile size in case sampling state changed. - * Should we really be doing this now if image size isn't set? - */ - if (tif->tif_tilesize > 0) - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); - if (tif->tif_scanlinesize > 0) - tif->tif_scanlinesize = TIFFScanlineSize(tif); -} - -static int JPEGVSetField(TIFF *tif, uint32_t tag, va_list ap) { - JPEGState *sp = JState(tif); - const TIFFField *fip; - uint32_t v32; - - assert(sp != NULL); - - switch (tag) { - case TIFFTAG_JPEGTABLES: - v32 = (uint32_t)va_arg(ap, uint32_t); - if (v32 == 0) { - /* XXX */ - return (0); - } - _TIFFsetByteArrayExt(tif, &sp->otherSettings.jpegtables, va_arg(ap, void *), v32); - sp->otherSettings.jpegtables_length = v32; - TIFFSetFieldBit(tif, FIELD_JPEGTABLES); - break; - case TIFFTAG_JPEGQUALITY: - sp->otherSettings.jpegquality = (int)va_arg(ap, int); - return (1); /* pseudo tag */ - case TIFFTAG_JPEGCOLORMODE: - sp->otherSettings.jpegcolormode = (int)va_arg(ap, int); - JPEGResetUpsampled(tif); - return (1); /* pseudo tag */ - case TIFFTAG_PHOTOMETRIC: { - int ret_value = (*sp->otherSettings.vsetparent)(tif, tag, ap); - JPEGResetUpsampled(tif); - return ret_value; - } - case TIFFTAG_JPEGTABLESMODE: - sp->otherSettings.jpegtablesmode = (int)va_arg(ap, int); - return (1); /* pseudo tag */ - case TIFFTAG_YCBCRSUBSAMPLING: - /* mark the fact that we have a real ycbcrsubsampling! */ - sp->otherSettings.ycbcrsampling_fetched = 1; - /* should we be recomputing upsampling info here? */ - return (*sp->otherSettings.vsetparent)(tif, tag, ap); - default: - return (*sp->otherSettings.vsetparent)(tif, tag, ap); - } - - if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) { - TIFFSetFieldBit(tif, fip->field_bit); - } else { - return (0); - } - - tif->tif_flags |= TIFF_DIRTYDIRECT; - return (1); -} - -static int JPEGVGetField(TIFF *tif, uint32_t tag, va_list ap) { - JPEGState *sp = JState(tif); - - assert(sp != NULL); - - switch (tag) { - case TIFFTAG_JPEGTABLES: - *va_arg(ap, uint32_t *) = sp->otherSettings.jpegtables_length; - *va_arg(ap, const void **) = sp->otherSettings.jpegtables; - break; - case TIFFTAG_JPEGQUALITY: - *va_arg(ap, int *) = sp->otherSettings.jpegquality; - break; - case TIFFTAG_JPEGCOLORMODE: - *va_arg(ap, int *) = sp->otherSettings.jpegcolormode; - break; - case TIFFTAG_JPEGTABLESMODE: - *va_arg(ap, int *) = sp->otherSettings.jpegtablesmode; - break; - default: - return (*sp->otherSettings.vgetparent)(tif, tag, ap); - } - return (1); -} - -static void JPEGPrintDir(TIFF *tif, FILE *fd, long flags) { - JPEGState *sp = JState(tif); - - assert(sp != NULL); - (void)flags; - - if (sp != NULL) { - if (TIFFFieldSet(tif, FIELD_JPEGTABLES)) - fprintf(fd, " JPEG Tables: (%" PRIu32 " bytes)\n", - sp->otherSettings.jpegtables_length); - if (sp->otherSettings.printdir) - (*sp->otherSettings.printdir)(tif, fd, flags); - } } -static uint32_t JPEGDefaultStripSize(TIFF *tif, uint32_t s) { - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; +static uint32_t JPEGDefaultStripSize(TIFF *tif, uint32_t s) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; - s = (*sp->otherSettings.defsparent)(tif, s); - if (s < td->td_imagelength) - s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE); - return (s); + s = (*sp->otherSettings.defsparent)(tif, s); + if (s < td->td_imagelength) + s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE); + return (s); } -static void JPEGDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) { - JPEGState *sp = JState(tif); - TIFFDirectory *td = &tif->tif_dir; +static void JPEGDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) +{ + JPEGState *sp = JState(tif); + TIFFDirectory *td = &tif->tif_dir; - (*sp->otherSettings.deftparent)(tif, tw, th); - *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); - *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); + (*sp->otherSettings.deftparent)(tif, tw, th); + *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE); + *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE); } /* @@ -2438,163 +2719,182 @@ static void JPEGDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) { * NFW, Feb 3rd, 2003. */ -static int JPEGInitializeLibJPEG(TIFF *tif, int decompress) { - JPEGState *sp = JState(tif); +static int JPEGInitializeLibJPEG(TIFF *tif, int decompress) +{ + JPEGState *sp = JState(tif); - if (sp->cinfo_initialized) { - if (!decompress && sp->cinfo.comm.is_decompressor) - TIFFjpeg_destroy(sp); - else if (decompress && !sp->cinfo.comm.is_decompressor) - TIFFjpeg_destroy(sp); + if (sp->cinfo_initialized) + { + if (!decompress && sp->cinfo.comm.is_decompressor) + TIFFjpeg_destroy(sp); + else if (decompress && !sp->cinfo.comm.is_decompressor) + TIFFjpeg_destroy(sp); + else + return 1; + + sp->cinfo_initialized = 0; + } + + /* + * Initialize libjpeg. + */ + if (decompress) + { + if (!TIFFjpeg_create_decompress(sp)) + return (0); + } else - return 1; - - sp->cinfo_initialized = 0; - } - - /* - * Initialize libjpeg. - */ - if (decompress) { - if (!TIFFjpeg_create_decompress(sp)) - return (0); - } else { - if (!TIFFjpeg_create_compress(sp)) - return (0); + { + if (!TIFFjpeg_create_compress(sp)) + return (0); #ifndef TIFF_JPEG_MAX_MEMORY_TO_USE #define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024) #endif - /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */ - /* store implementation, so better not set max_memory_to_use ourselves. */ - /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */ - if (sp->cinfo.c.mem->max_memory_to_use > 0) { - /* This is to address bug related in ticket GDAL #1795. */ - if (getenv("JPEGMEM") == NULL) { - /* Increase the max memory usable. This helps when creating files */ - /* with "big" tile, without using libjpeg temporary files. */ - /* For example a 512x512 tile with 3 bands */ - /* requires 1.5 MB which is above libjpeg 1MB default */ - if (sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE) - sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE; - } + /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */ + /* store implementation, so better not set max_memory_to_use ourselves. + */ + /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */ + if (sp->cinfo.c.mem->max_memory_to_use > 0) + { + /* This is to address bug related in ticket GDAL #1795. */ + if (getenv("JPEGMEM") == NULL) + { + /* Increase the max memory usable. This helps when creating + * files */ + /* with "big" tile, without using libjpeg temporary files. */ + /* For example a 512x512 tile with 3 bands */ + /* requires 1.5 MB which is above libjpeg 1MB default */ + if (sp->cinfo.c.mem->max_memory_to_use < + TIFF_JPEG_MAX_MEMORY_TO_USE) + sp->cinfo.c.mem->max_memory_to_use = + TIFF_JPEG_MAX_MEMORY_TO_USE; + } + } } - } - sp->cinfo_initialized = TRUE; + sp->cinfo_initialized = TRUE; - return 1; + return 1; } /* Common to tif_jpeg.c and tif_jpeg_12.c */ -static void TIFFInitJPEGCommon(TIFF *tif) { - JPEGState *sp; - - sp = JState(tif); - sp->tif = tif; /* back link */ - - /* Default values for codec-specific fields */ - sp->otherSettings.jpegtables = NULL; - sp->otherSettings.jpegtables_length = 0; - sp->otherSettings.jpegquality = 75; /* Default IJG quality */ - sp->otherSettings.jpegcolormode = JPEGCOLORMODE_RAW; - sp->otherSettings.jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; - sp->otherSettings.ycbcrsampling_fetched = 0; - - tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ - tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ - tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ - - /* - * Install codec methods. - */ - tif->tif_fixuptags = JPEGFixupTags; - tif->tif_setupdecode = JPEGSetupDecode; - tif->tif_predecode = JPEGPreDecode; - tif->tif_decoderow = JPEGDecode; - tif->tif_decodestrip = JPEGDecode; - tif->tif_decodetile = JPEGDecode; - tif->tif_setupencode = JPEGSetupEncode; - tif->tif_preencode = JPEGPreEncode; - tif->tif_postencode = JPEGPostEncode; - tif->tif_encoderow = JPEGEncode; - tif->tif_encodestrip = JPEGEncode; - tif->tif_encodetile = JPEGEncode; - tif->tif_cleanup = JPEGCleanup; - - tif->tif_defstripsize = JPEGDefaultStripSize; - tif->tif_deftilesize = JPEGDefaultTileSize; - tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ - sp->cinfo_initialized = FALSE; -} - -int TIFFInitJPEG(TIFF *tif, int scheme) { - JPEGState *sp; - - (void)scheme; - assert(scheme == COMPRESSION_JPEG); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) { - TIFFErrorExtR(tif, "TIFFInitJPEG", - "Merging JPEG codec-specific tags failed"); - return 0; - } +static void TIFFInitJPEGCommon(TIFF *tif) +{ + JPEGState *sp; - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(JPEGState)); + sp = JState(tif); + sp->tif = tif; /* back link */ + + /* Default values for codec-specific fields */ + sp->otherSettings.jpegtables = NULL; + sp->otherSettings.jpegtables_length = 0; + sp->otherSettings.jpegquality = 75; /* Default IJG quality */ + sp->otherSettings.jpegcolormode = JPEGCOLORMODE_RAW; + sp->otherSettings.jpegtablesmode = + JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF; + sp->otherSettings.ycbcrsampling_fetched = 0; + + tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */ + tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */ + tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */ - if (tif->tif_data == NULL) { - TIFFErrorExtR(tif, "TIFFInitJPEG", - "No space for JPEG state block"); - return 0; - } - _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); - - sp = JState(tif); - /* - * Override parent get/set field methods. - */ - sp->otherSettings.vgetparent = tif->tif_tagmethods.vgetfield; - sp->otherSettings.vsetparent = tif->tif_tagmethods.vsetfield; - sp->otherSettings.printdir = tif->tif_tagmethods.printdir; - - sp->otherSettings.defsparent = tif->tif_defstripsize; - sp->otherSettings.deftparent = tif->tif_deftilesize; - - TIFFInitJPEGCommon(tif); - - /* - ** Create a JPEGTables field if no directory has yet been created. - ** We do this just to ensure that sufficient space is reserved for - ** the JPEGTables field. It will be properly created the right - ** size later. - */ - if (tif->tif_diroff == 0) { -#define SIZE_OF_JPEGTABLES 2000 /* - The following line assumes incorrectly that all JPEG-in-TIFF files will have - a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be - written when the JPEG data is placed with TIFFWriteRawStrip. The field bit - should be set, anyway, later when actual JPEGTABLES header is generated, so - removing it here hopefully is harmless. TIFFSetFieldBit(tif, - FIELD_JPEGTABLES); - */ - sp->otherSettings.jpegtables_length = SIZE_OF_JPEGTABLES; - sp->otherSettings.jpegtables = - (void *)_TIFFmallocExt(tif, sp->otherSettings.jpegtables_length); - if (sp->otherSettings.jpegtables) { - _TIFFmemset(sp->otherSettings.jpegtables, 0, SIZE_OF_JPEGTABLES); - } else { - TIFFErrorExtR(tif, "TIFFInitJPEG", - "Failed to allocate memory for JPEG tables"); - return 0; + * Install codec methods. + */ + tif->tif_fixuptags = JPEGFixupTags; + tif->tif_setupdecode = JPEGSetupDecode; + tif->tif_predecode = JPEGPreDecode; + tif->tif_decoderow = JPEGDecode; + tif->tif_decodestrip = JPEGDecode; + tif->tif_decodetile = JPEGDecode; + tif->tif_setupencode = JPEGSetupEncode; + tif->tif_preencode = JPEGPreEncode; + tif->tif_postencode = JPEGPostEncode; + tif->tif_encoderow = JPEGEncode; + tif->tif_encodestrip = JPEGEncode; + tif->tif_encodetile = JPEGEncode; + tif->tif_cleanup = JPEGCleanup; + + tif->tif_defstripsize = JPEGDefaultStripSize; + tif->tif_deftilesize = JPEGDefaultTileSize; + tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */ + sp->cinfo_initialized = FALSE; +} + +int TIFFInitJPEG(TIFF *tif, int scheme) +{ + JPEGState *sp; + + (void)scheme; + assert(scheme == COMPRESSION_JPEG); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) + { + TIFFErrorExtR(tif, "TIFFInitJPEG", + "Merging JPEG codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(JPEGState)); + + if (tif->tif_data == NULL) + { + TIFFErrorExtR(tif, "TIFFInitJPEG", "No space for JPEG state block"); + return 0; } + _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); + + sp = JState(tif); + /* + * Override parent get/set field methods. + */ + sp->otherSettings.vgetparent = tif->tif_tagmethods.vgetfield; + sp->otherSettings.vsetparent = tif->tif_tagmethods.vsetfield; + sp->otherSettings.printdir = tif->tif_tagmethods.printdir; + + sp->otherSettings.defsparent = tif->tif_defstripsize; + sp->otherSettings.deftparent = tif->tif_deftilesize; + + TIFFInitJPEGCommon(tif); + + /* + ** Create a JPEGTables field if no directory has yet been created. + ** We do this just to ensure that sufficient space is reserved for + ** the JPEGTables field. It will be properly created the right + ** size later. + */ + if (tif->tif_diroff == 0) + { +#define SIZE_OF_JPEGTABLES 2000 + /* + The following line assumes incorrectly that all JPEG-in-TIFF files will + have a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags + to be written when the JPEG data is placed with TIFFWriteRawStrip. The + field bit should be set, anyway, later when actual JPEGTABLES header is + generated, so removing it here hopefully is harmless. + TIFFSetFieldBit(tif, FIELD_JPEGTABLES); + */ + sp->otherSettings.jpegtables_length = SIZE_OF_JPEGTABLES; + sp->otherSettings.jpegtables = + (void *)_TIFFmallocExt(tif, sp->otherSettings.jpegtables_length); + if (sp->otherSettings.jpegtables) + { + _TIFFmemset(sp->otherSettings.jpegtables, 0, SIZE_OF_JPEGTABLES); + } + else + { + TIFFErrorExtR(tif, "TIFFInitJPEG", + "Failed to allocate memory for JPEG tables"); + return 0; + } #undef SIZE_OF_JPEGTABLES - } - return 1; + } + return 1; } #endif /* JPEG_SUPPORT */ diff --git a/libtiff/tif_jpeg_12.c b/libtiff/tif_jpeg_12.c index 7fc5690e..406e1cfc 100644 --- a/libtiff/tif_jpeg_12.c +++ b/libtiff/tif_jpeg_12.c @@ -28,33 +28,36 @@ int TIFFInitJPEG_12(TIFF *tif, int scheme); #include "tif_jpeg.c" int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings, - int scheme, int is_encode) { - JPEGState *sp; - uint8_t *new_tif_data; + int scheme, int is_encode) +{ + JPEGState *sp; + uint8_t *new_tif_data; - (void)scheme; - assert(scheme == COMPRESSION_JPEG); + (void)scheme; + assert(scheme == COMPRESSION_JPEG); - new_tif_data = (uint8_t *)_TIFFreallocExt(tif, tif->tif_data, sizeof(JPEGState)); + new_tif_data = + (uint8_t *)_TIFFreallocExt(tif, tif->tif_data, sizeof(JPEGState)); - if (new_tif_data == NULL) { - TIFFErrorExtR(tif, "TIFFReInitJPEG_12", - "No space for JPEG state block"); - return 0; - } + if (new_tif_data == NULL) + { + TIFFErrorExtR(tif, "TIFFReInitJPEG_12", + "No space for JPEG state block"); + return 0; + } - tif->tif_data = new_tif_data; - _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); + tif->tif_data = new_tif_data; + _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState)); - TIFFInitJPEGCommon(tif); + TIFFInitJPEGCommon(tif); - sp = JState(tif); - sp->otherSettings = *otherSettings; + sp = JState(tif); + sp->otherSettings = *otherSettings; - if (is_encode) - return JPEGSetupEncode(tif); - else - return JPEGSetupDecode(tif); + if (is_encode) + return JPEGSetupEncode(tif); + else + return JPEGSetupDecode(tif); } #endif /* defined(JPEG_DUAL_MODE_8_12) */ diff --git a/libtiff/tif_lerc.c b/libtiff/tif_lerc.c index 430648ff..99de713c 100644 --- a/libtiff/tif_lerc.c +++ b/libtiff/tif_lerc.c @@ -1,35 +1,35 @@ /* -* Copyright (c) 2018, Even Rouault -* Author: <even.rouault at spatialys.com> -* -* Permission to use, copy, modify, distribute, and sell this software and -* its documentation for any purpose is hereby granted without fee, provided -* that (i) the above copyright notices and this permission notice appear in -* all copies of the software and related documentation, and (ii) the names of -* Sam Leffler and Silicon Graphics may not be used in any advertising or -* publicity relating to the software without the specific, prior written -* permission of Sam Leffler and Silicon Graphics. -* -* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -* -* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR -* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, -* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF -* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -* OF THIS SOFTWARE. -*/ + * Copyright (c) 2018, Even Rouault + * Author: <even.rouault at spatialys.com> + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ #include "tiffiop.h" #ifdef LERC_SUPPORT /* -* TIFF Library. -* -* LERC Compression Support -* -*/ + * TIFF Library. + * + * LERC Compression Support + * + */ #include "Lerc_c_api.h" #include "zlib.h" @@ -48,133 +48,127 @@ #define LSTATE_INIT_ENCODE 0x02 #ifndef LERC_AT_LEAST_VERSION -#define LERC_AT_LEAST_VERSION(maj,min,patch) 0 +#define LERC_AT_LEAST_VERSION(maj, min, patch) 0 #endif /* -* State block for each open TIFF file using LERC compression/decompression. -*/ -typedef struct { - double maxzerror; /* max z error */ - int lerc_version; - int additional_compression; - int zstd_compress_level; /* zstd */ - int zipquality; /* deflate */ - int state; /* state flags */ - - uint32_t segment_width; - uint32_t segment_height; - - unsigned int uncompressed_size; - unsigned int uncompressed_alloc; - uint8_t *uncompressed_buffer; - unsigned int uncompressed_offset; - - unsigned int mask_size; - uint8_t *mask_buffer; - - unsigned int compressed_size; - void *compressed_buffer; + * State block for each open TIFF file using LERC compression/decompression. + */ +typedef struct +{ + double maxzerror; /* max z error */ + int lerc_version; + int additional_compression; + int zstd_compress_level; /* zstd */ + int zipquality; /* deflate */ + int state; /* state flags */ + + uint32_t segment_width; + uint32_t segment_height; + + unsigned int uncompressed_size; + unsigned int uncompressed_alloc; + uint8_t *uncompressed_buffer; + unsigned int uncompressed_offset; + + unsigned int mask_size; + uint8_t *mask_buffer; + + unsigned int compressed_size; + void *compressed_buffer; #if LIBDEFLATE_SUPPORT - struct libdeflate_decompressor* libdeflate_dec; - struct libdeflate_compressor* libdeflate_enc; + struct libdeflate_decompressor *libdeflate_dec; + struct libdeflate_compressor *libdeflate_enc; #endif - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ } LERCState; -#define LState(tif) ((LERCState*) (tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) +#define LState(tif) ((LERCState *)(tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) -static int LERCEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s); -static int LERCDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s); +static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -static int -LERCFixupTags(TIFF* tif) +static int LERCFixupTags(TIFF *tif) { - (void) tif; - return 1; + (void)tif; + return 1; } -static int -LERCSetupDecode(TIFF* tif) +static int LERCSetupDecode(TIFF *tif) { - LERCState* sp = DecoderState(tif); + LERCState *sp = DecoderState(tif); - assert(sp != NULL); + assert(sp != NULL); - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) { - sp->state = 0; - } + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) + { + sp->state = 0; + } - sp->state |= LSTATE_INIT_DECODE; - return 1; + sp->state |= LSTATE_INIT_DECODE; + return 1; } -static int GetLercDataType(TIFF* tif) +static int GetLercDataType(TIFF *tif) { TIFFDirectory *td = &tif->tif_dir; static const char module[] = "GetLercDataType"; - if( td->td_sampleformat == SAMPLEFORMAT_INT && - td->td_bitspersample == 8 ) + if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 8) { return 0; } - if( td->td_sampleformat == SAMPLEFORMAT_UINT && - td->td_bitspersample == 8 ) + if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 8) { return 1; } - if( td->td_sampleformat == SAMPLEFORMAT_INT && - td->td_bitspersample == 16 ) + if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 16) { return 2; } - if( td->td_sampleformat == SAMPLEFORMAT_UINT && - td->td_bitspersample == 16 ) + if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 16) { return 3; } - if( td->td_sampleformat == SAMPLEFORMAT_INT && - td->td_bitspersample == 32 ) + if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 32) { return 4; } - if( td->td_sampleformat == SAMPLEFORMAT_UINT && - td->td_bitspersample == 32 ) + if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 32) { return 5; } - if( td->td_sampleformat == SAMPLEFORMAT_IEEEFP && - td->td_bitspersample == 32 ) + if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && + td->td_bitspersample == 32) { return 6; } - if( td->td_sampleformat == SAMPLEFORMAT_IEEEFP && - td->td_bitspersample == 64 ) + if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && + td->td_bitspersample == 64) { return 7; } - TIFFErrorExtR(tif, module, + TIFFErrorExtR( + tif, module, "Unsupported combination of SampleFormat and td_bitspersample"); return -1; } -static int SetupUncompressedBuffer(TIFF* tif, LERCState* sp, - const char* module) +static int SetupUncompressedBuffer(TIFF *tif, LERCState *sp, const char *module) { TIFFDirectory *td = &tif->tif_dir; uint64_t new_size_64; @@ -184,19 +178,22 @@ static int SetupUncompressedBuffer(TIFF* tif, LERCState* sp, sp->uncompressed_offset = 0; - if (isTiled(tif)) { - sp->segment_width = td->td_tilewidth; - sp->segment_height = td->td_tilelength; - } else { - sp->segment_width = td->td_imagewidth; - sp->segment_height = td->td_imagelength - tif->tif_row; - if (sp->segment_height > td->td_rowsperstrip) - sp->segment_height = td->td_rowsperstrip; + if (isTiled(tif)) + { + sp->segment_width = td->td_tilewidth; + sp->segment_height = td->td_tilelength; + } + else + { + sp->segment_width = td->td_imagewidth; + sp->segment_height = td->td_imagelength - tif->tif_row; + if (sp->segment_height > td->td_rowsperstrip) + sp->segment_height = td->td_rowsperstrip; } new_size_64 = (uint64_t)sp->segment_width * sp->segment_height * - (td->td_bitspersample / 8); - if( td->td_planarconfig == PLANARCONFIG_CONTIG ) + (td->td_bitspersample / 8); + if (td->td_planarconfig == PLANARCONFIG_CONTIG) { new_size_64 *= td->td_samplesperpixel; } @@ -204,36 +201,35 @@ static int SetupUncompressedBuffer(TIFF* tif, LERCState* sp, new_size = (unsigned int)new_size_64; sp->uncompressed_size = new_size; - /* add some margin as we are going to use it also to store deflate/zstd compressed data */ + /* add some margin as we are going to use it also to store deflate/zstd + * compressed data */ new_alloc_64 = 100 + new_size_64 + new_size_64 / 3; #ifdef ZSTD_SUPPORT { size_t zstd_max = ZSTD_compressBound((size_t)new_size_64); - if( new_alloc_64 < zstd_max ) + if (new_alloc_64 < zstd_max) { new_alloc_64 = zstd_max; } } #endif new_alloc = (unsigned int)new_alloc_64; - if( new_alloc != new_alloc_64 ) + if (new_alloc != new_alloc_64) { - TIFFErrorExtR(tif, module, - "Too large uncompressed strip/tile"); + TIFFErrorExtR(tif, module, "Too large uncompressed strip/tile"); _TIFFfreeExt(tif, sp->uncompressed_buffer); sp->uncompressed_buffer = 0; sp->uncompressed_alloc = 0; return 0; } - if( sp->uncompressed_alloc < new_alloc ) + if (sp->uncompressed_alloc < new_alloc) { _TIFFfreeExt(tif, sp->uncompressed_buffer); sp->uncompressed_buffer = _TIFFmallocExt(tif, new_alloc); - if( !sp->uncompressed_buffer ) + if (!sp->uncompressed_buffer) { - TIFFErrorExtR(tif, module, - "Cannot allocate buffer"); + TIFFErrorExtR(tif, module, "Cannot allocate buffer"); _TIFFfreeExt(tif, sp->uncompressed_buffer); sp->uncompressed_buffer = 0; sp->uncompressed_alloc = 0; @@ -242,30 +238,30 @@ static int SetupUncompressedBuffer(TIFF* tif, LERCState* sp, sp->uncompressed_alloc = new_alloc; } - if( (td->td_planarconfig == PLANARCONFIG_CONTIG && + if ((td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 && - td->td_sampleinfo[td->td_extrasamples-1] == EXTRASAMPLE_UNASSALPHA && - GetLercDataType(tif) == 1 ) || + td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && + GetLercDataType(tif) == 1) || (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && (td->td_planarconfig == PLANARCONFIG_SEPARATE || - td->td_samplesperpixel == 1) && - (td->td_bitspersample == 32 || td->td_bitspersample == 64 )) ) + td->td_samplesperpixel == 1) && + (td->td_bitspersample == 32 || td->td_bitspersample == 64))) { unsigned int mask_size = sp->segment_width * sp->segment_height; - if( sp->mask_size < mask_size ) + if (sp->mask_size < mask_size) { - void* mask_buffer = _TIFFreallocExt(tif, sp->mask_buffer, mask_size); - if( mask_buffer == NULL ) + void *mask_buffer = + _TIFFreallocExt(tif, sp->mask_buffer, mask_size); + if (mask_buffer == NULL) { - TIFFErrorExtR(tif, module, - "Cannot allocate buffer"); + TIFFErrorExtR(tif, module, "Cannot allocate buffer"); sp->mask_size = 0; _TIFFfreeExt(tif, sp->uncompressed_buffer); sp->uncompressed_buffer = 0; sp->uncompressed_alloc = 0; return 0; } - sp->mask_buffer = (uint8_t*)mask_buffer; + sp->mask_buffer = (uint8_t *)mask_buffer; sp->mask_size = mask_size; } } @@ -274,546 +270,498 @@ static int SetupUncompressedBuffer(TIFF* tif, LERCState* sp, } /* -* Setup state for decoding a strip. -*/ -static int -LERCPreDecode(TIFF* tif, uint16_t s) + * Setup state for decoding a strip. + */ +static int LERCPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "LERCPreDecode"; - lerc_status lerc_ret; - TIFFDirectory *td = &tif->tif_dir; - LERCState* sp = DecoderState(tif); - int lerc_data_type; - unsigned int infoArray[8]; - unsigned nomask_bands = td->td_samplesperpixel; - int ndims; - int use_mask = 0; - uint8_t* lerc_data = tif->tif_rawcp; - unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc; - - (void) s; - assert(sp != NULL); - if( sp->state != LSTATE_INIT_DECODE ) - tif->tif_setupdecode(tif); - - lerc_data_type = GetLercDataType(tif); - if( lerc_data_type < 0 ) - return 0; + static const char module[] = "LERCPreDecode"; + lerc_status lerc_ret; + TIFFDirectory *td = &tif->tif_dir; + LERCState *sp = DecoderState(tif); + int lerc_data_type; + unsigned int infoArray[8]; + unsigned nomask_bands = td->td_samplesperpixel; + int ndims; + int use_mask = 0; + uint8_t *lerc_data = tif->tif_rawcp; + unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc; + + (void)s; + assert(sp != NULL); + if (sp->state != LSTATE_INIT_DECODE) + tif->tif_setupdecode(tif); + + lerc_data_type = GetLercDataType(tif); + if (lerc_data_type < 0) + return 0; - if( !SetupUncompressedBuffer(tif, sp, module) ) - return 0; + if (!SetupUncompressedBuffer(tif, sp, module)) + return 0; - if( sp->additional_compression != LERC_ADD_COMPRESSION_NONE ) + if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE) + { + if (sp->compressed_size < sp->uncompressed_alloc) { - if( sp->compressed_size < sp->uncompressed_alloc ) + _TIFFfreeExt(tif, sp->compressed_buffer); + sp->compressed_buffer = _TIFFmallocExt(tif, sp->uncompressed_alloc); + if (!sp->compressed_buffer) { - _TIFFfreeExt(tif, sp->compressed_buffer); - sp->compressed_buffer = _TIFFmallocExt(tif, sp->uncompressed_alloc); - if( !sp->compressed_buffer ) - { - sp->compressed_size = 0; - return 0; - } - sp->compressed_size = sp->uncompressed_alloc; + sp->compressed_size = 0; + return 0; } + sp->compressed_size = sp->uncompressed_alloc; } + } - if( sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE ) - { + if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE) + { #if LIBDEFLATE_SUPPORT - enum libdeflate_result res; - size_t lerc_data_sizet = 0; - if( sp->libdeflate_dec == NULL ) - { - sp->libdeflate_dec = libdeflate_alloc_decompressor(); - if( sp->libdeflate_dec == NULL ) - { - TIFFErrorExtR(tif, module, - "Cannot allocate decompressor"); - return 0; - } - } - - res = libdeflate_zlib_decompress( - sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc, - sp->compressed_buffer, sp->compressed_size, - &lerc_data_sizet); - if( res != LIBDEFLATE_SUCCESS ) - { - TIFFErrorExtR(tif, module, - "Decoding error at scanline %lu", - (unsigned long) tif->tif_row); - return 0; - } - assert( lerc_data_sizet == (unsigned int)lerc_data_sizet ); - lerc_data = sp->compressed_buffer; - lerc_data_size = (unsigned int)lerc_data_sizet; -#else - z_stream strm; - int zlib_ret; - - memset(&strm, 0, sizeof(strm)); - strm.zalloc = NULL; - strm.zfree = NULL; - strm.opaque = NULL; - zlib_ret = inflateInit(&strm); - if( zlib_ret != Z_OK ) - { - TIFFErrorExtR(tif, module, - "inflateInit() failed"); - inflateEnd(&strm); - return 0; - } - - strm.avail_in = (uInt)tif->tif_rawcc; - strm.next_in = tif->tif_rawcp; - strm.avail_out = sp->compressed_size; - strm.next_out = sp->compressed_buffer; - zlib_ret = inflate(&strm, Z_FINISH); - if( zlib_ret != Z_STREAM_END && zlib_ret != Z_OK ) + enum libdeflate_result res; + size_t lerc_data_sizet = 0; + if (sp->libdeflate_dec == NULL) + { + sp->libdeflate_dec = libdeflate_alloc_decompressor(); + if (sp->libdeflate_dec == NULL) { - TIFFErrorExtR(tif, module, - "inflate() failed"); - inflateEnd(&strm); + TIFFErrorExtR(tif, module, "Cannot allocate decompressor"); return 0; } - lerc_data = sp->compressed_buffer; - lerc_data_size = sp->compressed_size - strm.avail_out; - inflateEnd(&strm); -#endif } - else if( sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD ) - { -#ifdef ZSTD_SUPPORT - size_t zstd_ret; - zstd_ret = ZSTD_decompress(sp->compressed_buffer, - sp->compressed_size, - tif->tif_rawcp, - tif->tif_rawcc); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExtR(tif, module, - "Error in ZSTD_decompress(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - - lerc_data = sp->compressed_buffer; - lerc_data_size = (unsigned int)zstd_ret; -#else - TIFFErrorExtR(tif, module, "ZSTD support missing"); + res = libdeflate_zlib_decompress( + sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc, + sp->compressed_buffer, sp->compressed_size, &lerc_data_sizet); + if (res != LIBDEFLATE_SUCCESS) + { + TIFFErrorExtR(tif, module, "Decoding error at scanline %lu", + (unsigned long)tif->tif_row); return 0; -#endif } - else if( sp->additional_compression != LERC_ADD_COMPRESSION_NONE ) + assert(lerc_data_sizet == (unsigned int)lerc_data_sizet); + lerc_data = sp->compressed_buffer; + lerc_data_size = (unsigned int)lerc_data_sizet; +#else + z_stream strm; + int zlib_ret; + + memset(&strm, 0, sizeof(strm)); + strm.zalloc = NULL; + strm.zfree = NULL; + strm.opaque = NULL; + zlib_ret = inflateInit(&strm); + if (zlib_ret != Z_OK) { - TIFFErrorExtR(tif, module, - "Unhandled additional compression"); + TIFFErrorExtR(tif, module, "inflateInit() failed"); + inflateEnd(&strm); return 0; } - lerc_ret = lerc_getBlobInfo( - lerc_data, - lerc_data_size, - infoArray, - NULL, - 8, - 0); - if( lerc_ret != 0 ) + strm.avail_in = (uInt)tif->tif_rawcc; + strm.next_in = tif->tif_rawcp; + strm.avail_out = sp->compressed_size; + strm.next_out = sp->compressed_buffer; + zlib_ret = inflate(&strm, Z_FINISH); + if (zlib_ret != Z_STREAM_END && zlib_ret != Z_OK) { - TIFFErrorExtR(tif, module, - "lerc_getBlobInfo() failed"); + TIFFErrorExtR(tif, module, "inflate() failed"); + inflateEnd(&strm); return 0; } + lerc_data = sp->compressed_buffer; + lerc_data_size = sp->compressed_size - strm.avail_out; + inflateEnd(&strm); +#endif + } + else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD) + { +#ifdef ZSTD_SUPPORT + size_t zstd_ret; - /* If the configuration is compatible of a LERC mask, and that the */ - /* LERC info has dim == samplesperpixel - 1, then there is a LERC */ - /* mask. */ - if( td->td_planarconfig == PLANARCONFIG_CONTIG && - td->td_extrasamples > 0 && - td->td_sampleinfo[td->td_extrasamples-1] == EXTRASAMPLE_UNASSALPHA && - GetLercDataType(tif) == 1 && - infoArray[2] == td->td_samplesperpixel - 1U ) + zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size, + tif->tif_rawcp, tif->tif_rawcc); + if (ZSTD_isError(zstd_ret)) { - use_mask = 1; - nomask_bands --; - } - else if( td->td_sampleformat == SAMPLEFORMAT_IEEEFP && - (td->td_planarconfig == PLANARCONFIG_SEPARATE || - td->td_samplesperpixel == 1) && - (td->td_bitspersample == 32 || td->td_bitspersample == 64) ) - { - use_mask = 1; + TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; } - ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? - nomask_bands : 1; + lerc_data = sp->compressed_buffer; + lerc_data_size = (unsigned int)zstd_ret; +#else + TIFFErrorExtR(tif, module, "ZSTD support missing"); + return 0; +#endif + } + else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE) + { + TIFFErrorExtR(tif, module, "Unhandled additional compression"); + return 0; + } - /* Info returned in infoArray is { version, dataType, nDim, nCols, - nRows, nBands, nValidPixels, blobSize } */ - if( infoArray[0] != (unsigned)sp->lerc_version ) - { - TIFFWarningExtR(tif, module, - "Unexpected version number: %d. Expected: %d", - infoArray[0], sp->lerc_version); - } - if( infoArray[1] != (unsigned)lerc_data_type ) - { - TIFFErrorExtR(tif, module, - "Unexpected dataType: %d. Expected: %d", - infoArray[1], lerc_data_type); - return 0; - } - if( infoArray[2] != (unsigned)ndims ) - { - TIFFErrorExtR(tif, module, - "Unexpected nDim: %d. Expected: %d", - infoArray[2], ndims); - return 0; - } - if( infoArray[3] != sp->segment_width ) - { - TIFFErrorExtR(tif, module, - "Unexpected nCols: %d. Expected: %du", - infoArray[3], sp->segment_width); - return 0; - } - if( infoArray[4] != sp->segment_height ) - { - TIFFErrorExtR(tif, module, - "Unexpected nRows: %d. Expected: %u", - infoArray[4], sp->segment_height); - return 0; - } - if( infoArray[5] != 1 ) - { - TIFFErrorExtR(tif, module, - "Unexpected nBands: %d. Expected: %d", - infoArray[5], 1); - return 0; - } - if( infoArray[7] != lerc_data_size ) - { - TIFFErrorExtR(tif, module, - "Unexpected blobSize: %d. Expected: %u", - infoArray[7], - lerc_data_size); - return 0; - } + lerc_ret = + lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 8, 0); + if (lerc_ret != 0) + { + TIFFErrorExtR(tif, module, "lerc_getBlobInfo() failed"); + return 0; + } + + /* If the configuration is compatible of a LERC mask, and that the */ + /* LERC info has dim == samplesperpixel - 1, then there is a LERC */ + /* mask. */ + if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 && + td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && + GetLercDataType(tif) == 1 && + infoArray[2] == td->td_samplesperpixel - 1U) + { + use_mask = 1; + nomask_bands--; + } + else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && + (td->td_planarconfig == PLANARCONFIG_SEPARATE || + td->td_samplesperpixel == 1) && + (td->td_bitspersample == 32 || td->td_bitspersample == 64)) + { + use_mask = 1; + } - lerc_ret = lerc_decode( - lerc_data, - lerc_data_size, -#if LERC_AT_LEAST_VERSION(3,0,0) - use_mask ? 1 : 0, + ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1; + + /* Info returned in infoArray is { version, dataType, nDim, nCols, + nRows, nBands, nValidPixels, blobSize } */ + if (infoArray[0] != (unsigned)sp->lerc_version) + { + TIFFWarningExtR(tif, module, + "Unexpected version number: %d. Expected: %d", + infoArray[0], sp->lerc_version); + } + if (infoArray[1] != (unsigned)lerc_data_type) + { + TIFFErrorExtR(tif, module, "Unexpected dataType: %d. Expected: %d", + infoArray[1], lerc_data_type); + return 0; + } + if (infoArray[2] != (unsigned)ndims) + { + TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: %d", + infoArray[2], ndims); + return 0; + } + if (infoArray[3] != sp->segment_width) + { + TIFFErrorExtR(tif, module, "Unexpected nCols: %d. Expected: %du", + infoArray[3], sp->segment_width); + return 0; + } + if (infoArray[4] != sp->segment_height) + { + TIFFErrorExtR(tif, module, "Unexpected nRows: %d. Expected: %u", + infoArray[4], sp->segment_height); + return 0; + } + if (infoArray[5] != 1) + { + TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d", + infoArray[5], 1); + return 0; + } + if (infoArray[7] != lerc_data_size) + { + TIFFErrorExtR(tif, module, "Unexpected blobSize: %d. Expected: %u", + infoArray[7], lerc_data_size); + return 0; + } + + lerc_ret = lerc_decode(lerc_data, lerc_data_size, +#if LERC_AT_LEAST_VERSION(3, 0, 0) + use_mask ? 1 : 0, #endif - use_mask ? sp->mask_buffer : NULL, - ndims, - sp->segment_width, - sp->segment_height, - 1, - lerc_data_type, - sp->uncompressed_buffer); - if( lerc_ret != 0 ) - { - TIFFErrorExtR(tif, module, - "lerc_decode() failed"); - return 0; - } + use_mask ? sp->mask_buffer : NULL, ndims, + sp->segment_width, sp->segment_height, 1, + lerc_data_type, sp->uncompressed_buffer); + if (lerc_ret != 0) + { + TIFFErrorExtR(tif, module, "lerc_decode() failed"); + return 0; + } - /* Interleave alpha mask with other samples. */ - if( use_mask && GetLercDataType(tif) == 1 ) + /* Interleave alpha mask with other samples. */ + if (use_mask && GetLercDataType(tif) == 1) + { + unsigned src_stride = + (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); + unsigned dst_stride = + td->td_samplesperpixel * (td->td_bitspersample / 8); + unsigned i = sp->segment_width * sp->segment_height; + /* Operate from end to begin to be able to move in place */ + while (i > 0 && i > nomask_bands) { - unsigned src_stride = - (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); - unsigned dst_stride = - td->td_samplesperpixel * (td->td_bitspersample / 8); - unsigned i = sp->segment_width * sp->segment_height; - /* Operate from end to begin to be able to move in place */ - while( i > 0 && i > nomask_bands ) - { - i --; - sp->uncompressed_buffer[ - i * dst_stride + td->td_samplesperpixel - 1] = - 255 * sp->mask_buffer[i]; - memcpy( sp->uncompressed_buffer + i * dst_stride, - sp->uncompressed_buffer + i * src_stride, - src_stride ); - } - /* First pixels must use memmove due to overlapping areas */ - while( i > 0 ) - { - i --; - sp->uncompressed_buffer[ - i * dst_stride + td->td_samplesperpixel - 1] = - 255 * sp->mask_buffer[i]; - memmove( sp->uncompressed_buffer + i * dst_stride, - sp->uncompressed_buffer + i * src_stride, - src_stride ); - } + i--; + sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel - + 1] = 255 * sp->mask_buffer[i]; + memcpy(sp->uncompressed_buffer + i * dst_stride, + sp->uncompressed_buffer + i * src_stride, src_stride); } - else if( use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP ) + /* First pixels must use memmove due to overlapping areas */ + while (i > 0) { - const unsigned nb_pixels = sp->segment_width * sp->segment_height; - unsigned i; + i--; + sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel - + 1] = 255 * sp->mask_buffer[i]; + memmove(sp->uncompressed_buffer + i * dst_stride, + sp->uncompressed_buffer + i * src_stride, src_stride); + } + } + else if (use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP) + { + const unsigned nb_pixels = sp->segment_width * sp->segment_height; + unsigned i; #if HOST_BIGENDIAN - const unsigned char nan_bytes[] = { 0x7f, 0xc0, 0, 0 }; + const unsigned char nan_bytes[] = {0x7f, 0xc0, 0, 0}; #else - const unsigned char nan_bytes[] = { 0, 0, 0xc0, 0x7f }; + const unsigned char nan_bytes[] = {0, 0, 0xc0, 0x7f}; #endif - float nan_float32; - memcpy(&nan_float32, nan_bytes, 4); + float nan_float32; + memcpy(&nan_float32, nan_bytes, 4); - if( td->td_bitspersample == 32 ) + if (td->td_bitspersample == 32) + { + for (i = 0; i < nb_pixels; i++) { - for( i = 0; i < nb_pixels; i++ ) - { - if( sp->mask_buffer[i] == 0 ) - ((float*)sp->uncompressed_buffer)[i] = nan_float32; - } + if (sp->mask_buffer[i] == 0) + ((float *)sp->uncompressed_buffer)[i] = nan_float32; } - else + } + else + { + const double nan_float64 = nan_float32; + for (i = 0; i < nb_pixels; i++) { - const double nan_float64 = nan_float32; - for( i = 0; i < nb_pixels; i++ ) - { - if( sp->mask_buffer[i] == 0 ) - ((double*)sp->uncompressed_buffer)[i] = nan_float64; - } + if (sp->mask_buffer[i] == 0) + ((double *)sp->uncompressed_buffer)[i] = nan_float64; } } + } - return 1; + return 1; } /* -* Decode a strip, tile or scanline. -*/ -static int -LERCDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) + * Decode a strip, tile or scanline. + */ +static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "LERCDecode"; - LERCState* sp = DecoderState(tif); + static const char module[] = "LERCDecode"; + LERCState *sp = DecoderState(tif); - (void) s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); + (void)s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); - if( sp->uncompressed_buffer == 0 ) - { - TIFFErrorExtR(tif, module, - "Uncompressed buffer not allocated"); - return 0; - } + if (sp->uncompressed_buffer == 0) + { + TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated"); + return 0; + } - if( (uint64_t)sp->uncompressed_offset + - (uint64_t)occ > sp->uncompressed_size ) - { - TIFFErrorExtR(tif, module, - "Too many bytes read"); - return 0; - } + if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ > + sp->uncompressed_size) + { + TIFFErrorExtR(tif, module, "Too many bytes read"); + return 0; + } - memcpy(op, - sp->uncompressed_buffer + sp->uncompressed_offset, - occ); - sp->uncompressed_offset += (unsigned)occ; + memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, occ); + sp->uncompressed_offset += (unsigned)occ; - return 1; + return 1; } -static int -LERCSetupEncode(TIFF* tif) +static int LERCSetupEncode(TIFF *tif) { - LERCState* sp = EncoderState(tif); + LERCState *sp = EncoderState(tif); - assert(sp != NULL); - if (sp->state & LSTATE_INIT_DECODE) { - sp->state = 0; - } + assert(sp != NULL); + if (sp->state & LSTATE_INIT_DECODE) + { + sp->state = 0; + } - sp->state |= LSTATE_INIT_ENCODE; + sp->state |= LSTATE_INIT_ENCODE; - return 1; + return 1; } /* -* Reset encoding state at the start of a strip. -*/ -static int -LERCPreEncode(TIFF* tif, uint16_t s) + * Reset encoding state at the start of a strip. + */ +static int LERCPreEncode(TIFF *tif, uint16_t s) { - static const char module[] = "LERCPreEncode"; - LERCState *sp = EncoderState(tif); - int lerc_data_type; + static const char module[] = "LERCPreEncode"; + LERCState *sp = EncoderState(tif); + int lerc_data_type; - (void) s; - assert(sp != NULL); - if( sp->state != LSTATE_INIT_ENCODE ) - tif->tif_setupencode(tif); + (void)s; + assert(sp != NULL); + if (sp->state != LSTATE_INIT_ENCODE) + tif->tif_setupencode(tif); - lerc_data_type = GetLercDataType(tif); - if( lerc_data_type < 0 ) - return 0; + lerc_data_type = GetLercDataType(tif); + if (lerc_data_type < 0) + return 0; - if( !SetupUncompressedBuffer(tif, sp, module) ) - return 0; + if (!SetupUncompressedBuffer(tif, sp, module)) + return 0; - return 1; + return 1; } /* -* Encode a chunk of pixels. -*/ -static int -LERCEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) + * Encode a chunk of pixels. + */ +static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "LERCEncode"; - LERCState *sp = EncoderState(tif); + static const char module[] = "LERCEncode"; + LERCState *sp = EncoderState(tif); - (void)s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); + (void)s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); - if( (uint64_t)sp->uncompressed_offset + - (uint64_t)cc > sp->uncompressed_size ) - { - TIFFErrorExtR(tif, module, - "Too many bytes written"); - return 0; - } + if ((uint64_t)sp->uncompressed_offset + (uint64_t)cc > + sp->uncompressed_size) + { + TIFFErrorExtR(tif, module, "Too many bytes written"); + return 0; + } - memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, - bp, cc); - sp->uncompressed_offset += (unsigned)cc; + memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, cc); + sp->uncompressed_offset += (unsigned)cc; - return 1; + return 1; } /* -* Finish off an encoded strip by flushing it. -*/ -static int -LERCPostEncode(TIFF* tif) + * Finish off an encoded strip by flushing it. + */ +static int LERCPostEncode(TIFF *tif) { - lerc_status lerc_ret; - static const char module[] = "LERCPostEncode"; - LERCState *sp = EncoderState(tif); - unsigned int numBytes = 0; - unsigned int numBytesWritten = 0; - TIFFDirectory *td = &tif->tif_dir; - int use_mask = 0; - unsigned dst_nbands = td->td_samplesperpixel; - - if( sp->uncompressed_offset != sp->uncompressed_size ) + lerc_status lerc_ret; + static const char module[] = "LERCPostEncode"; + LERCState *sp = EncoderState(tif); + unsigned int numBytes = 0; + unsigned int numBytesWritten = 0; + TIFFDirectory *td = &tif->tif_dir; + int use_mask = 0; + unsigned dst_nbands = td->td_samplesperpixel; + + if (sp->uncompressed_offset != sp->uncompressed_size) + { + TIFFErrorExtR(tif, module, "Unexpected number of bytes in the buffer"); + return 0; + } + + /* Extract alpha mask (if containing only 0 and 255 values, */ + /* and compact array of regular bands */ + if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 && + td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA && + GetLercDataType(tif) == 1) + { + const unsigned dst_stride = + (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8); + const unsigned src_stride = + td->td_samplesperpixel * (td->td_bitspersample / 8); + unsigned i = 0; + const unsigned nb_pixels = sp->segment_width * sp->segment_height; + + use_mask = 1; + for (i = 0; i < nb_pixels; i++) { - TIFFErrorExtR(tif, module, - "Unexpected number of bytes in the buffer"); - return 0; + int v = sp->uncompressed_buffer[i * src_stride + + td->td_samplesperpixel - 1]; + if (v != 0 && v != 255) + { + use_mask = 0; + break; + } } - /* Extract alpha mask (if containing only 0 and 255 values, */ - /* and compact array of regular bands */ - if( td->td_planarconfig == PLANARCONFIG_CONTIG && - td->td_extrasamples > 0 && - td->td_sampleinfo[td->td_extrasamples-1] == EXTRASAMPLE_UNASSALPHA && - GetLercDataType(tif) == 1 ) + if (use_mask) { - const unsigned dst_stride = (td->td_samplesperpixel - 1) * - (td->td_bitspersample / 8); - const unsigned src_stride = td->td_samplesperpixel * - (td->td_bitspersample / 8); - unsigned i = 0; - const unsigned nb_pixels = sp->segment_width * sp->segment_height; - - use_mask = 1; - for( i = 0 ; i < nb_pixels; i++) + dst_nbands--; + /* First pixels must use memmove due to overlapping areas */ + for (i = 0; i < dst_nbands && i < nb_pixels; i++) { - int v = sp->uncompressed_buffer[ - i * src_stride + td->td_samplesperpixel - 1]; - if( v != 0 && v != 255 ) - { - use_mask = 0; - break; - } + memmove(sp->uncompressed_buffer + i * dst_stride, + sp->uncompressed_buffer + i * src_stride, dst_stride); + sp->mask_buffer[i] = + sp->uncompressed_buffer[i * src_stride + + td->td_samplesperpixel - 1]; } - - if( use_mask ) + for (; i < nb_pixels; i++) { - dst_nbands --; - /* First pixels must use memmove due to overlapping areas */ - for( i = 0 ;i < dst_nbands && i < nb_pixels; i++) - { - memmove( sp->uncompressed_buffer + i * dst_stride, - sp->uncompressed_buffer + i * src_stride, - dst_stride ); - sp->mask_buffer[i] = sp->uncompressed_buffer[ - i * src_stride + td->td_samplesperpixel - 1]; - } - for(; i < nb_pixels; i++) - { - memcpy( sp->uncompressed_buffer + i * dst_stride, - sp->uncompressed_buffer + i * src_stride, - dst_stride ); - sp->mask_buffer[i] = sp->uncompressed_buffer[ - i * src_stride + td->td_samplesperpixel - 1]; - } + memcpy(sp->uncompressed_buffer + i * dst_stride, + sp->uncompressed_buffer + i * src_stride, dst_stride); + sp->mask_buffer[i] = + sp->uncompressed_buffer[i * src_stride + + td->td_samplesperpixel - 1]; } } - else if( td->td_sampleformat == SAMPLEFORMAT_IEEEFP && - (td->td_planarconfig == PLANARCONFIG_SEPARATE || - dst_nbands == 1) && - (td->td_bitspersample == 32 || td->td_bitspersample == 64 ) ) + } + else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && + (td->td_planarconfig == PLANARCONFIG_SEPARATE || + dst_nbands == 1) && + (td->td_bitspersample == 32 || td->td_bitspersample == 64)) + { + /* Check for NaN values */ + unsigned i; + const unsigned nb_pixels = sp->segment_width * sp->segment_height; + if (td->td_bitspersample == 32) { - /* Check for NaN values */ - unsigned i; - const unsigned nb_pixels = sp->segment_width * sp->segment_height; - if( td->td_bitspersample == 32 ) + for (i = 0; i < nb_pixels; i++) { - for( i = 0; i < nb_pixels; i++ ) + const float val = ((float *)sp->uncompressed_buffer)[i]; + if (val != val) { - const float val = ((float*)sp->uncompressed_buffer)[i]; - if( val != val ) - { - use_mask = 1; - break; - } + use_mask = 1; + break; } } - else + } + else + { + for (i = 0; i < nb_pixels; i++) { - for( i = 0; i < nb_pixels; i++ ) + const double val = ((double *)sp->uncompressed_buffer)[i]; + if (val != val) { - const double val = ((double*)sp->uncompressed_buffer)[i]; - if( val != val ) - { - use_mask = 1; - break; - } + use_mask = 1; + break; } } + } - if( use_mask ) + if (use_mask) + { + if (td->td_bitspersample == 32) { - if( td->td_bitspersample == 32 ) + for (i = 0; i < nb_pixels; i++) { - for( i = 0; i < nb_pixels; i++ ) - { - const float val = ((float*)sp->uncompressed_buffer)[i]; - sp->mask_buffer[i] = ( val == val ) ? 255 : 0; - } + const float val = ((float *)sp->uncompressed_buffer)[i]; + sp->mask_buffer[i] = (val == val) ? 255 : 0; } - else + } + else + { + for (i = 0; i < nb_pixels; i++) { - for( i = 0; i < nb_pixels; i++ ) - { - const double val = ((double*)sp->uncompressed_buffer)[i]; - sp->mask_buffer[i] = ( val == val ) ? 255 : 0; - } + const double val = ((double *)sp->uncompressed_buffer)[i]; + sp->mask_buffer[i] = (val == val) ? 255 : 0; } } } - + } #if 0 lerc_ret = lerc_computeCompressedSize( @@ -835,237 +783,219 @@ LERCPostEncode(TIFF* tif) return 0; } #else - numBytes = sp->uncompressed_alloc; + numBytes = sp->uncompressed_alloc; #endif - if( sp->compressed_size < numBytes ) + if (sp->compressed_size < numBytes) + { + _TIFFfreeExt(tif, sp->compressed_buffer); + sp->compressed_buffer = _TIFFmallocExt(tif, numBytes); + if (!sp->compressed_buffer) { - _TIFFfreeExt(tif, sp->compressed_buffer); - sp->compressed_buffer = _TIFFmallocExt(tif, numBytes); - if( !sp->compressed_buffer ) + sp->compressed_size = 0; + return 0; + } + sp->compressed_size = numBytes; + } + + lerc_ret = lerc_encodeForVersion( + sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif), + td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1, + sp->segment_width, sp->segment_height, 1, +#if LERC_AT_LEAST_VERSION(3, 0, 0) + use_mask ? 1 : 0, +#endif + use_mask ? sp->mask_buffer : NULL, sp->maxzerror, sp->compressed_buffer, + sp->compressed_size, &numBytesWritten); + if (lerc_ret != 0) + { + TIFFErrorExtR(tif, module, "lerc_encode() failed"); + return 0; + } + assert(numBytesWritten < numBytes); + + if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE) + { +#if LIBDEFLATE_SUPPORT + if (sp->libdeflate_enc == NULL) + { + /* To get results as good as zlib, we ask for an extra */ + /* level of compression */ + sp->libdeflate_enc = libdeflate_alloc_compressor( + sp->zipquality == Z_DEFAULT_COMPRESSION ? 7 + : sp->zipquality >= 6 && sp->zipquality <= 9 + ? sp->zipquality + 1 + : sp->zipquality); + if (sp->libdeflate_enc == NULL) { - sp->compressed_size = 0; + TIFFErrorExtR(tif, module, "Cannot allocate compressor"); return 0; } - sp->compressed_size = numBytes; } - lerc_ret = lerc_encodeForVersion( - sp->uncompressed_buffer, - sp->lerc_version, - GetLercDataType(tif), - td->td_planarconfig == PLANARCONFIG_CONTIG ? - dst_nbands : 1, - sp->segment_width, - sp->segment_height, - 1, -#if LERC_AT_LEAST_VERSION(3,0,0) - use_mask ? 1 : 0, -#endif - use_mask ? sp->mask_buffer : NULL, - sp->maxzerror, - sp->compressed_buffer, - sp->compressed_size, - &numBytesWritten); - if( lerc_ret != 0 ) + /* Should not happen normally */ + if (libdeflate_zlib_compress_bound( + sp->libdeflate_enc, numBytesWritten) > sp->uncompressed_alloc) { TIFFErrorExtR(tif, module, - "lerc_encode() failed"); + "Output buffer for libdeflate too small"); return 0; } - assert( numBytesWritten < numBytes ); - - if( sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE ) - { -#if LIBDEFLATE_SUPPORT - if( sp->libdeflate_enc == NULL ) - { - /* To get results as good as zlib, we ask for an extra */ - /* level of compression */ - sp->libdeflate_enc = libdeflate_alloc_compressor( - sp->zipquality == Z_DEFAULT_COMPRESSION ? 7 : - sp->zipquality >= 6 && sp->zipquality <= 9 ? sp->zipquality + 1 : - sp->zipquality); - if( sp->libdeflate_enc == NULL ) - { - TIFFErrorExtR(tif, module, - "Cannot allocate compressor"); - return 0; - } - } - - /* Should not happen normally */ - if( libdeflate_zlib_compress_bound(sp->libdeflate_enc, numBytesWritten) > - sp->uncompressed_alloc ) - { - TIFFErrorExtR(tif, module, - "Output buffer for libdeflate too small"); - return 0; - } - tif->tif_rawcc = libdeflate_zlib_compress( - sp->libdeflate_enc, - sp->compressed_buffer, numBytesWritten, - sp->uncompressed_buffer, sp->uncompressed_alloc); + tif->tif_rawcc = libdeflate_zlib_compress( + sp->libdeflate_enc, sp->compressed_buffer, numBytesWritten, + sp->uncompressed_buffer, sp->uncompressed_alloc); - if( tif->tif_rawcc == 0 ) - { - TIFFErrorExtR(tif, module, - "Encoder error at scanline %lu", - (unsigned long) tif->tif_row); - return 0; - } + if (tif->tif_rawcc == 0) + { + TIFFErrorExtR(tif, module, "Encoder error at scanline %lu", + (unsigned long)tif->tif_row); + return 0; + } #else - z_stream strm; - int zlib_ret; - int cappedQuality = sp->zipquality; - if( cappedQuality > Z_BEST_COMPRESSION ) - cappedQuality = Z_BEST_COMPRESSION; - - memset(&strm, 0, sizeof(strm)); - strm.zalloc = NULL; - strm.zfree = NULL; - strm.opaque = NULL; - zlib_ret = deflateInit(&strm, cappedQuality); - if( zlib_ret != Z_OK ) - { - TIFFErrorExtR(tif, module, - "deflateInit() failed"); - return 0; - } + z_stream strm; + int zlib_ret; + int cappedQuality = sp->zipquality; + if (cappedQuality > Z_BEST_COMPRESSION) + cappedQuality = Z_BEST_COMPRESSION; + + memset(&strm, 0, sizeof(strm)); + strm.zalloc = NULL; + strm.zfree = NULL; + strm.opaque = NULL; + zlib_ret = deflateInit(&strm, cappedQuality); + if (zlib_ret != Z_OK) + { + TIFFErrorExtR(tif, module, "deflateInit() failed"); + return 0; + } - strm.avail_in = numBytesWritten; - strm.next_in = sp->compressed_buffer; - strm.avail_out = sp->uncompressed_alloc; - strm.next_out = sp->uncompressed_buffer; - zlib_ret = deflate(&strm, Z_FINISH); - if( zlib_ret == Z_STREAM_END ) - { - tif->tif_rawcc = sp->uncompressed_alloc - strm.avail_out; - } - deflateEnd(&strm); - if( zlib_ret != Z_STREAM_END ) - { - TIFFErrorExtR(tif, module, - "deflate() failed"); - return 0; - } -#endif - { - int ret; - uint8_t* tif_rawdata_backup = tif->tif_rawdata; - tif->tif_rawdata = sp->uncompressed_buffer; - ret = TIFFFlushData1(tif); - tif->tif_rawdata = tif_rawdata_backup; - if( !ret ) - { - return 0; - } - } + strm.avail_in = numBytesWritten; + strm.next_in = sp->compressed_buffer; + strm.avail_out = sp->uncompressed_alloc; + strm.next_out = sp->uncompressed_buffer; + zlib_ret = deflate(&strm, Z_FINISH); + if (zlib_ret == Z_STREAM_END) + { + tif->tif_rawcc = sp->uncompressed_alloc - strm.avail_out; } - else if( sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD ) + deflateEnd(&strm); + if (zlib_ret != Z_STREAM_END) { -#ifdef ZSTD_SUPPORT - size_t zstd_ret = ZSTD_compress( sp->uncompressed_buffer, - sp->uncompressed_alloc, - sp->compressed_buffer, - numBytesWritten, - sp->zstd_compress_level ); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExtR(tif, module, - "Error in ZSTD_compress(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - - { - int ret; - uint8_t* tif_rawdata_backup = tif->tif_rawdata; - tif->tif_rawdata = sp->uncompressed_buffer; - tif->tif_rawcc = zstd_ret; - ret = TIFFFlushData1(tif); - tif->tif_rawdata = tif_rawdata_backup; - if( !ret ) - { - return 0; - } - } -#else - TIFFErrorExtR(tif, module, "ZSTD support missing"); + TIFFErrorExtR(tif, module, "deflate() failed"); return 0; + } #endif + { + int ret; + uint8_t *tif_rawdata_backup = tif->tif_rawdata; + tif->tif_rawdata = sp->uncompressed_buffer; + ret = TIFFFlushData1(tif); + tif->tif_rawdata = tif_rawdata_backup; + if (!ret) + { + return 0; + } } - else if( sp->additional_compression != LERC_ADD_COMPRESSION_NONE ) + } + else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD) + { +#ifdef ZSTD_SUPPORT + size_t zstd_ret = ZSTD_compress( + sp->uncompressed_buffer, sp->uncompressed_alloc, + sp->compressed_buffer, numBytesWritten, sp->zstd_compress_level); + if (ZSTD_isError(zstd_ret)) { - TIFFErrorExtR(tif, module, - "Unhandled additional compression"); + TIFFErrorExtR(tif, module, "Error in ZSTD_compress(): %s", + ZSTD_getErrorName(zstd_ret)); return 0; } - else + { int ret; - uint8_t* tif_rawdata_backup = tif->tif_rawdata; - tif->tif_rawdata = sp->compressed_buffer; - tif->tif_rawcc = numBytesWritten; + uint8_t *tif_rawdata_backup = tif->tif_rawdata; + tif->tif_rawdata = sp->uncompressed_buffer; + tif->tif_rawcc = zstd_ret; ret = TIFFFlushData1(tif); tif->tif_rawdata = tif_rawdata_backup; - if( !ret ) + if (!ret) + { return 0; + } } +#else + TIFFErrorExtR(tif, module, "ZSTD support missing"); + return 0; +#endif + } + else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE) + { + TIFFErrorExtR(tif, module, "Unhandled additional compression"); + return 0; + } + else + { + int ret; + uint8_t *tif_rawdata_backup = tif->tif_rawdata; + tif->tif_rawdata = sp->compressed_buffer; + tif->tif_rawcc = numBytesWritten; + ret = TIFFFlushData1(tif); + tif->tif_rawdata = tif_rawdata_backup; + if (!ret) + return 0; + } - return 1; + return 1; } -static void -LERCCleanup(TIFF* tif) +static void LERCCleanup(TIFF *tif) { - LERCState* sp = LState(tif); + LERCState *sp = LState(tif); - assert(sp != 0); + assert(sp != 0); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; - _TIFFfreeExt(tif, sp->uncompressed_buffer); - _TIFFfreeExt(tif, sp->compressed_buffer); - _TIFFfreeExt(tif, sp->mask_buffer); + _TIFFfreeExt(tif, sp->uncompressed_buffer); + _TIFFfreeExt(tif, sp->compressed_buffer); + _TIFFfreeExt(tif, sp->mask_buffer); #if LIBDEFLATE_SUPPORT - if( sp->libdeflate_dec ) - libdeflate_free_decompressor(sp->libdeflate_dec); - if( sp->libdeflate_enc ) - libdeflate_free_compressor(sp->libdeflate_enc); + if (sp->libdeflate_dec) + libdeflate_free_decompressor(sp->libdeflate_dec); + if (sp->libdeflate_enc) + libdeflate_free_compressor(sp->libdeflate_enc); #endif - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } static const TIFFField LERCFields[] = { - { TIFFTAG_LERC_PARAMETERS, TIFF_VARIABLE2, TIFF_VARIABLE2, - TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, - FIELD_CUSTOM, FALSE, TRUE, "LercParameters", NULL }, - { TIFFTAG_LERC_MAXZERROR, 0, 0, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, - TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, TRUE, FALSE, "LercMaximumError", NULL }, - { TIFFTAG_LERC_VERSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, - TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, FALSE, FALSE, "LercVersion", NULL }, - { TIFFTAG_LERC_ADD_COMPRESSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, - TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, FALSE, FALSE, "LercAdditionalCompression", NULL }, - { TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, TRUE, FALSE, "ZSTD zstd_compress_level", NULL }, - { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, + {TIFFTAG_LERC_PARAMETERS, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG, 0, + TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, FALSE, TRUE, + "LercParameters", NULL}, + {TIFFTAG_LERC_MAXZERROR, 0, 0, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "LercMaximumError", + NULL}, + {TIFFTAG_LERC_VERSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "LercVersion", NULL}, + {TIFFTAG_LERC_ADD_COMPRESSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, + "LercAdditionalCompression", NULL}, + {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, + "ZSTD zstd_compress_level", NULL}, + {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, }; -static int LERCVSetFieldBase(TIFF* tif, uint32_t tag, ...) +static int LERCVSetFieldBase(TIFF *tif, uint32_t tag, ...) { - LERCState* sp = LState(tif); + LERCState *sp = LState(tif); int ret; va_list ap; va_start(ap, tag); @@ -1074,80 +1004,78 @@ static int LERCVSetFieldBase(TIFF* tif, uint32_t tag, ...) return ret; } -static int -LERCVSetField(TIFF* tif, uint32_t tag, va_list ap) +static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[] = "LERCVSetField"; - LERCState* sp = LState(tif); + static const char module[] = "LERCVSetField"; + LERCState *sp = LState(tif); - switch (tag) { + switch (tag) + { case TIFFTAG_LERC_PARAMETERS: { - uint32_t count = va_arg(ap, int); - int* params = va_arg(ap, int*); - if( count < 2 ) - { - TIFFErrorExtR(tif, module, - "Invalid count for LercParameters: %u", count); - return 0; - } - sp->lerc_version = params[0]; - sp->additional_compression = params[1]; - return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, - count, params); + uint32_t count = va_arg(ap, int); + int *params = va_arg(ap, int *); + if (count < 2) + { + TIFFErrorExtR(tif, module, + "Invalid count for LercParameters: %u", count); + return 0; + } + sp->lerc_version = params[0]; + sp->additional_compression = params[1]; + return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, count, + params); } case TIFFTAG_LERC_MAXZERROR: - sp->maxzerror = va_arg(ap, double); - return 1; + sp->maxzerror = va_arg(ap, double); + return 1; case TIFFTAG_LERC_VERSION: { - int params[2] = {0, 0}; - int version = va_arg(ap, int); - if( version != LERC_VERSION_2_4 ) - { - TIFFErrorExtR(tif, module, - "Invalid value for LercVersion: %d", version); - return 0; - } - sp->lerc_version = version; - params[0] = sp->lerc_version; - params[1] = sp->additional_compression; - return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, - 2, params); + int params[2] = {0, 0}; + int version = va_arg(ap, int); + if (version != LERC_VERSION_2_4) + { + TIFFErrorExtR(tif, module, "Invalid value for LercVersion: %d", + version); + return 0; + } + sp->lerc_version = version; + params[0] = sp->lerc_version; + params[1] = sp->additional_compression; + return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params); } case TIFFTAG_LERC_ADD_COMPRESSION: { - int params[2] = {0, 0}; - int additional_compression = va_arg(ap, int); + int params[2] = {0, 0}; + int additional_compression = va_arg(ap, int); #ifndef ZSTD_SUPPORT - if( additional_compression == LERC_ADD_COMPRESSION_ZSTD ) - { - TIFFErrorExtR(tif, module, - "LERC_ZSTD requested, but ZSTD not available"); - return 0; - } + if (additional_compression == LERC_ADD_COMPRESSION_ZSTD) + { + TIFFErrorExtR(tif, module, + "LERC_ZSTD requested, but ZSTD not available"); + return 0; + } #endif - if( additional_compression != LERC_ADD_COMPRESSION_NONE && - additional_compression != LERC_ADD_COMPRESSION_DEFLATE && - additional_compression != LERC_ADD_COMPRESSION_ZSTD ) - { - TIFFErrorExtR(tif, module, - "Invalid value for LercAdditionalCompression: %d", - additional_compression); - return 0; - } - sp->additional_compression = additional_compression; - params[0] = sp->lerc_version; - params[1] = sp->additional_compression; - return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, - 2, params); + if (additional_compression != LERC_ADD_COMPRESSION_NONE && + additional_compression != LERC_ADD_COMPRESSION_DEFLATE && + additional_compression != LERC_ADD_COMPRESSION_ZSTD) + { + TIFFErrorExtR(tif, module, + "Invalid value for LercAdditionalCompression: %d", + additional_compression); + return 0; + } + sp->additional_compression = additional_compression; + params[0] = sp->lerc_version; + params[1] = sp->additional_compression; + return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params); } #ifdef ZSTD_SUPPORT case TIFFTAG_ZSTD_LEVEL: { - sp->zstd_compress_level = (int) va_arg(ap, int); - if( sp->zstd_compress_level <= 0 || - sp->zstd_compress_level > ZSTD_maxCLevel() ) + sp->zstd_compress_level = (int)va_arg(ap, int); + if (sp->zstd_compress_level <= 0 || + sp->zstd_compress_level > ZSTD_maxCLevel()) { TIFFWarningExtR(tif, module, "ZSTD_LEVEL should be between 1 and %d", @@ -1156,122 +1084,123 @@ LERCVSetField(TIFF* tif, uint32_t tag, va_list ap) return 1; } #endif - case TIFFTAG_ZIPQUALITY: + case TIFFTAG_ZIPQUALITY: { - sp->zipquality = (int) va_arg(ap, int); - if( sp->zipquality < Z_DEFAULT_COMPRESSION || - sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL ) { - TIFFErrorExtR(tif, module, - "Invalid ZipQuality value. Should be in [-1,%d] range", - LIBDEFLATE_MAX_COMPRESSION_LEVEL); - return 0; - } + sp->zipquality = (int)va_arg(ap, int); + if (sp->zipquality < Z_DEFAULT_COMPRESSION || + sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL) + { + TIFFErrorExtR( + tif, module, + "Invalid ZipQuality value. Should be in [-1,%d] range", + LIBDEFLATE_MAX_COMPRESSION_LEVEL); + return 0; + } #if LIBDEFLATE_SUPPORT - if( sp->libdeflate_enc ) - { - libdeflate_free_compressor(sp->libdeflate_enc); - sp->libdeflate_enc = NULL; - } + if (sp->libdeflate_enc) + { + libdeflate_free_compressor(sp->libdeflate_enc); + sp->libdeflate_enc = NULL; + } #endif - return (1); + return (1); } default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ } -static int -LERCVGetField(TIFF* tif, uint32_t tag, va_list ap) +static int LERCVGetField(TIFF *tif, uint32_t tag, va_list ap) { - LERCState* sp = LState(tif); + LERCState *sp = LState(tif); - switch (tag) { + switch (tag) + { case TIFFTAG_LERC_MAXZERROR: - *va_arg(ap, double*) = sp->maxzerror; - break; + *va_arg(ap, double *) = sp->maxzerror; + break; case TIFFTAG_LERC_VERSION: - *va_arg(ap, int*) = sp->lerc_version; - break; + *va_arg(ap, int *) = sp->lerc_version; + break; case TIFFTAG_LERC_ADD_COMPRESSION: - *va_arg(ap, int*) = sp->additional_compression; - break; + *va_arg(ap, int *) = sp->additional_compression; + break; case TIFFTAG_ZSTD_LEVEL: - *va_arg(ap, int*) = sp->zstd_compress_level; - break; + *va_arg(ap, int *) = sp->zstd_compress_level; + break; case TIFFTAG_ZIPQUALITY: - *va_arg(ap, int*) = sp->zipquality; - break; + *va_arg(ap, int *) = sp->zipquality; + break; default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; } -int TIFFInitLERC(TIFF* tif, int scheme) +int TIFFInitLERC(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitLERC"; - LERCState* sp; + static const char module[] = "TIFFInitLERC"; + LERCState *sp; - (void) scheme; - assert( scheme == COMPRESSION_LERC ); + (void)scheme; + assert(scheme == COMPRESSION_LERC); - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields))) { - TIFFErrorExtR(tif, module, - "Merging LERC codec-specific tags failed"); - return 0; - } + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields))) + { + TIFFErrorExtR(tif, module, "Merging LERC codec-specific tags failed"); + return 0; + } - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t*) _TIFFcallocExt(tif, 1, sizeof(LERCState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */ - - /* - * Install codec methods. - */ - tif->tif_fixuptags = LERCFixupTags; - tif->tif_setupdecode = LERCSetupDecode; - tif->tif_predecode = LERCPreDecode; - tif->tif_decoderow = LERCDecode; - tif->tif_decodestrip = LERCDecode; - tif->tif_decodetile = LERCDecode; - tif->tif_setupencode = LERCSetupEncode; - tif->tif_preencode = LERCPreEncode; - tif->tif_postencode = LERCPostEncode; - tif->tif_encoderow = LERCEncode; - tif->tif_encodestrip = LERCEncode; - tif->tif_encodetile = LERCEncode; - tif->tif_cleanup = LERCCleanup; - - /* Default values for codec-specific fields */ - TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4); - TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE); - sp->maxzerror = 0.0; - sp->zstd_compress_level = 9; /* default comp. level */ - sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ - sp->state = 0; + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */ + + /* + * Install codec methods. + */ + tif->tif_fixuptags = LERCFixupTags; + tif->tif_setupdecode = LERCSetupDecode; + tif->tif_predecode = LERCPreDecode; + tif->tif_decoderow = LERCDecode; + tif->tif_decodestrip = LERCDecode; + tif->tif_decodetile = LERCDecode; + tif->tif_setupencode = LERCSetupEncode; + tif->tif_preencode = LERCPreEncode; + tif->tif_postencode = LERCPostEncode; + tif->tif_encoderow = LERCEncode; + tif->tif_encodestrip = LERCEncode; + tif->tif_encodetile = LERCEncode; + tif->tif_cleanup = LERCCleanup; + + /* Default values for codec-specific fields */ + TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4); + TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE); + sp->maxzerror = 0.0; + sp->zstd_compress_level = 9; /* default comp. level */ + sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ + sp->state = 0; - return 1; + return 1; bad: - TIFFErrorExtR(tif, module, - "No space for LERC state block"); - return 0; + TIFFErrorExtR(tif, module, "No space for LERC state block"); + return 0; } #endif /* LERC_SUPPORT */ diff --git a/libtiff/tif_luv.c b/libtiff/tif_luv.c index 90dda2db..051721e8 100644 --- a/libtiff/tif_luv.c +++ b/libtiff/tif_luv.c @@ -2,23 +2,23 @@ * Copyright (c) 1997 Greg Ward Larson * Copyright (c) 1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any * advertising or publicity relating to the software without the specific, * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -34,7 +34,7 @@ * LogLuv image support uses the TIFF library to store 16 or 10-bit * log luminance values with 8 bits each of u and v or a 14-bit index. * - * The codec can take as input and produce as output 32-bit IEEE float values + * The codec can take as input and produce as output 32-bit IEEE float values * as well as 16-bit integer values. A 16-bit luminance is interpreted * as a sign bit followed by a 15-bit integer that is converted * to and from a linear magnitude using the transformation: @@ -145,9 +145,9 @@ * quantization errors into noise. */ +#include <math.h> #include <stdio.h> #include <stdlib.h> -#include <math.h> /* * State block for each open TIFF @@ -155,22 +155,23 @@ */ typedef struct logLuvState LogLuvState; -struct logLuvState { - int encoder_state; /* 1 if encoder correctly initialized */ - int user_datafmt; /* user data format */ - int encode_meth; /* encoding method */ - int pixel_size; /* bytes per pixel */ +struct logLuvState +{ + int encoder_state; /* 1 if encoder correctly initialized */ + int user_datafmt; /* user data format */ + int encode_meth; /* encoding method */ + int pixel_size; /* bytes per pixel */ - uint8_t* tbuf; /* translation buffer */ - tmsize_t tbuflen; /* buffer length */ - void (*tfunc)(LogLuvState*, uint8_t*, tmsize_t); + uint8_t *tbuf; /* translation buffer */ + tmsize_t tbuflen; /* buffer length */ + void (*tfunc)(LogLuvState *, uint8_t *, tmsize_t); - TIFFVSetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVSetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ }; -#define DecoderState(tif) ((LogLuvState*) (tif)->tif_data) -#define EncoderState(tif) ((LogLuvState*) (tif)->tif_data) +#define DecoderState(tif) ((LogLuvState *)(tif)->tif_data) +#define EncoderState(tif) ((LogLuvState *)(tif)->tif_data) #define SGILOGDATAFMT_UNKNOWN -1 @@ -179,193 +180,207 @@ struct logLuvState { /* * Decode a string of 16-bit gray pixels. */ -static int -LogL16Decode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) +static int LogL16Decode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "LogL16Decode"; - LogLuvState* sp = DecoderState(tif); - int shft; - tmsize_t i; - tmsize_t npixels; - unsigned char* bp; - int16_t* tp; - int16_t b; - tmsize_t cc; - int rc; - - (void)s; - assert(s == 0); - assert(sp != NULL); - - npixels = occ / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_16BIT) - tp = (int16_t*) op; - else { - if(sp->tbuflen < npixels) { - TIFFErrorExtR(tif, module, - "Translation buffer too short"); - return (0); - } - tp = (int16_t*) sp->tbuf; - } - _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); - - bp = (unsigned char*) tif->tif_rawcp; - cc = tif->tif_rawcc; - /* get each byte string */ - for (shft = 8; shft >= 0; shft -=8) { - for (i = 0; i < npixels && cc > 0; ) { - if (*bp >= 128) { /* run */ - if( cc < 2 ) - break; - rc = *bp++ + (2-128); - b = (int16_t)(*bp++ << shft); - cc -= 2; - while (rc-- && i < npixels) - tp[i++] |= b; - } else { /* non-run */ - rc = *bp++; /* nul is noop */ - while (--cc && rc-- && i < npixels) - tp[i++] |= (int16_t)*bp++ << shft; - } - } - if (i != npixels) { - TIFFErrorExtR(tif, module, - "Not enough data at row %"PRIu32" (short %"TIFF_SSIZE_FORMAT" pixels)", - tif->tif_row, - npixels - i); - tif->tif_rawcp = (uint8_t*) bp; - tif->tif_rawcc = cc; - return (0); - } - } - (*sp->tfunc)(sp, op, npixels); - tif->tif_rawcp = (uint8_t*) bp; - tif->tif_rawcc = cc; - return (1); + static const char module[] = "LogL16Decode"; + LogLuvState *sp = DecoderState(tif); + int shft; + tmsize_t i; + tmsize_t npixels; + unsigned char *bp; + int16_t *tp; + int16_t b; + tmsize_t cc; + int rc; + + (void)s; + assert(s == 0); + assert(sp != NULL); + + npixels = occ / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_16BIT) + tp = (int16_t *)op; + else + { + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + tp = (int16_t *)sp->tbuf; + } + _TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0])); + + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + /* get each byte string */ + for (shft = 8; shft >= 0; shft -= 8) + { + for (i = 0; i < npixels && cc > 0;) + { + if (*bp >= 128) + { /* run */ + if (cc < 2) + break; + rc = *bp++ + (2 - 128); + b = (int16_t)(*bp++ << shft); + cc -= 2; + while (rc-- && i < npixels) + tp[i++] |= b; + } + else + { /* non-run */ + rc = *bp++; /* nul is noop */ + while (--cc && rc-- && i < npixels) + tp[i++] |= (int16_t)*bp++ << shft; + } + } + if (i != npixels) + { + TIFFErrorExtR(tif, module, + "Not enough data at row %" PRIu32 + " (short %" TIFF_SSIZE_FORMAT " pixels)", + tif->tif_row, npixels - i); + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + return (0); + } + } + (*sp->tfunc)(sp, op, npixels); + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + return (1); } /* * Decode a string of 24-bit pixels. */ -static int -LogLuvDecode24(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) +static int LogLuvDecode24(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "LogLuvDecode24"; - LogLuvState* sp = DecoderState(tif); - tmsize_t cc; - tmsize_t i; - tmsize_t npixels; - unsigned char* bp; - uint32_t* tp; - - (void)s; - assert(s == 0); - assert(sp != NULL); - - npixels = occ / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32_t *)op; - else { - if(sp->tbuflen < npixels) { - TIFFErrorExtR(tif, module, - "Translation buffer too short"); - return (0); - } - tp = (uint32_t *) sp->tbuf; - } - /* copy to array of uint32_t */ - bp = (unsigned char*) tif->tif_rawcp; - cc = tif->tif_rawcc; - for (i = 0; i < npixels && cc >= 3; i++) { - tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; - bp += 3; - cc -= 3; - } - tif->tif_rawcp = (uint8_t*) bp; - tif->tif_rawcc = cc; - if (i != npixels) { - TIFFErrorExtR(tif, module, - "Not enough data at row %"PRIu32" (short %"TIFF_SSIZE_FORMAT" pixels)", - tif->tif_row, - npixels - i); - return (0); - } - (*sp->tfunc)(sp, op, npixels); - return (1); + static const char module[] = "LogLuvDecode24"; + LogLuvState *sp = DecoderState(tif); + tmsize_t cc; + tmsize_t i; + tmsize_t npixels; + unsigned char *bp; + uint32_t *tp; + + (void)s; + assert(s == 0); + assert(sp != NULL); + + npixels = occ / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32_t *)op; + else + { + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + tp = (uint32_t *)sp->tbuf; + } + /* copy to array of uint32_t */ + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + for (i = 0; i < npixels && cc >= 3; i++) + { + tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2]; + bp += 3; + cc -= 3; + } + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + if (i != npixels) + { + TIFFErrorExtR(tif, module, + "Not enough data at row %" PRIu32 + " (short %" TIFF_SSIZE_FORMAT " pixels)", + tif->tif_row, npixels - i); + return (0); + } + (*sp->tfunc)(sp, op, npixels); + return (1); } /* * Decode a string of 32-bit pixels. */ -static int -LogLuvDecode32(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) +static int LogLuvDecode32(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "LogLuvDecode32"; - LogLuvState* sp; - int shft; - tmsize_t i; - tmsize_t npixels; - unsigned char* bp; - uint32_t* tp; - uint32_t b; - tmsize_t cc; - int rc; - - (void)s; - assert(s == 0); - sp = DecoderState(tif); - assert(sp != NULL); - - npixels = occ / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32_t*) op; - else { - if(sp->tbuflen < npixels) { - TIFFErrorExtR(tif, module, - "Translation buffer too short"); - return (0); - } - tp = (uint32_t*) sp->tbuf; - } - _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0])); - - bp = (unsigned char*) tif->tif_rawcp; - cc = tif->tif_rawcc; - /* get each byte string */ - for (shft = 24; shft >= 0; shft -=8) { - for (i = 0; i < npixels && cc > 0; ) { - if (*bp >= 128) { /* run */ - if( cc < 2 ) - break; - rc = *bp++ + (2-128); - b = (uint32_t)*bp++ << shft; - cc -= 2; - while (rc-- && i < npixels) - tp[i++] |= b; - } else { /* non-run */ - rc = *bp++; /* nul is noop */ - while (--cc && rc-- && i < npixels) - tp[i++] |= (uint32_t)*bp++ << shft; - } - } - if (i != npixels) { - TIFFErrorExtR(tif, module, - "Not enough data at row %"PRIu32" (short %"TIFF_SSIZE_FORMAT" pixels)", - tif->tif_row, - npixels - i); - tif->tif_rawcp = (uint8_t*) bp; - tif->tif_rawcc = cc; - return (0); - } - } - (*sp->tfunc)(sp, op, npixels); - tif->tif_rawcp = (uint8_t*) bp; - tif->tif_rawcc = cc; - return (1); + static const char module[] = "LogLuvDecode32"; + LogLuvState *sp; + int shft; + tmsize_t i; + tmsize_t npixels; + unsigned char *bp; + uint32_t *tp; + uint32_t b; + tmsize_t cc; + int rc; + + (void)s; + assert(s == 0); + sp = DecoderState(tif); + assert(sp != NULL); + + npixels = occ / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32_t *)op; + else + { + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + tp = (uint32_t *)sp->tbuf; + } + _TIFFmemset((void *)tp, 0, npixels * sizeof(tp[0])); + + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + /* get each byte string */ + for (shft = 24; shft >= 0; shft -= 8) + { + for (i = 0; i < npixels && cc > 0;) + { + if (*bp >= 128) + { /* run */ + if (cc < 2) + break; + rc = *bp++ + (2 - 128); + b = (uint32_t)*bp++ << shft; + cc -= 2; + while (rc-- && i < npixels) + tp[i++] |= b; + } + else + { /* non-run */ + rc = *bp++; /* nul is noop */ + while (--cc && rc-- && i < npixels) + tp[i++] |= (uint32_t)*bp++ << shft; + } + } + if (i != npixels) + { + TIFFErrorExtR(tif, module, + "Not enough data at row %" PRIu32 + " (short %" TIFF_SSIZE_FORMAT " pixels)", + tif->tif_row, npixels - i); + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + return (0); + } + } + (*sp->tfunc)(sp, op, npixels); + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + return (1); } /* @@ -373,20 +388,20 @@ LogLuvDecode32(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) * maintain synchrony with the encode algorithm, which * is row by row. */ -static int -LogLuvDecodeStrip(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int LogLuvDecodeStrip(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - tmsize_t rowlen = TIFFScanlineSize(tif); - - if (rowlen == 0) - return 0; - - assert(cc%rowlen == 0); - while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); + tmsize_t rowlen = TIFFScanlineSize(tif); + + if (rowlen == 0) + return 0; + + assert(cc % rowlen == 0); + while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) + { + bp += rowlen; + cc -= rowlen; + } + return (cc == 0); } /* @@ -394,314 +409,342 @@ LogLuvDecodeStrip(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) * maintain synchrony with the encode algorithm, which * is row by row. */ -static int -LogLuvDecodeTile(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int LogLuvDecodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - tmsize_t rowlen = TIFFTileRowSize(tif); - - if (rowlen == 0) - return 0; - - assert(cc%rowlen == 0); - while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); + tmsize_t rowlen = TIFFTileRowSize(tif); + + if (rowlen == 0) + return 0; + + assert(cc % rowlen == 0); + while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s)) + { + bp += rowlen; + cc -= rowlen; + } + return (cc == 0); } /* * Encode a row of 16-bit pixels. */ -static int -LogL16Encode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int LogL16Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "LogL16Encode"; - LogLuvState* sp = EncoderState(tif); - int shft; - tmsize_t i; - tmsize_t j; - tmsize_t npixels; - uint8_t* op; - int16_t* tp; - int16_t b; - tmsize_t occ; - int rc=0, mask; - tmsize_t beg; - - (void)s; - assert(s == 0); - assert(sp != NULL); - npixels = cc / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_16BIT) - tp = (int16_t*) bp; - else { - tp = (int16_t*) sp->tbuf; - if(sp->tbuflen < npixels) { - TIFFErrorExtR(tif, module, - "Translation buffer too short"); - return (0); - } - (*sp->tfunc)(sp, bp, npixels); - } - /* compress each byte string */ - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (shft = 8; shft >= 0; shft -=8) { - for (i = 0; i < npixels; i += rc) { - if (occ < 4) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - mask = 0xff << shft; /* find next run */ - for (beg = i; beg < npixels; beg += rc) { - b = (int16_t) (tp[beg] & mask); - rc = 1; - while (rc < 127+2 && beg+rc < npixels && - (tp[beg+rc] & mask) == b) - rc++; - if (rc >= MINRUN) - break; /* long enough */ - } - if (beg-i > 1 && beg-i < MINRUN) { - b = (int16_t) (tp[i] & mask);/*check short run */ - j = i+1; - while ((tp[j++] & mask) == b) - if (j == beg) { - *op++ = (uint8_t)(128 - 2 + j - i); - *op++ = (uint8_t)(b >> shft); - occ -= 2; - i = beg; - break; - } - } - while (i < beg) { /* write out non-run */ - if ((j = beg-i) > 127) j = 127; - if (occ < j+3) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - *op++ = (uint8_t) j; occ--; - while (j--) { - *op++ = (uint8_t) (tp[i++] >> shft & 0xff); - occ--; - } - } - if (rc >= MINRUN) { /* write out run */ - *op++ = (uint8_t) (128 - 2 + rc); - *op++ = (uint8_t) (tp[beg] >> shft & 0xff); - occ -= 2; - } else - rc = 0; - } - } - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - - return (1); + static const char module[] = "LogL16Encode"; + LogLuvState *sp = EncoderState(tif); + int shft; + tmsize_t i; + tmsize_t j; + tmsize_t npixels; + uint8_t *op; + int16_t *tp; + int16_t b; + tmsize_t occ; + int rc = 0, mask; + tmsize_t beg; + + (void)s; + assert(s == 0); + assert(sp != NULL); + npixels = cc / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_16BIT) + tp = (int16_t *)bp; + else + { + tp = (int16_t *)sp->tbuf; + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + (*sp->tfunc)(sp, bp, npixels); + } + /* compress each byte string */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (shft = 8; shft >= 0; shft -= 8) + { + for (i = 0; i < npixels; i += rc) + { + if (occ < 4) + { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + mask = 0xff << shft; /* find next run */ + for (beg = i; beg < npixels; beg += rc) + { + b = (int16_t)(tp[beg] & mask); + rc = 1; + while (rc < 127 + 2 && beg + rc < npixels && + (tp[beg + rc] & mask) == b) + rc++; + if (rc >= MINRUN) + break; /* long enough */ + } + if (beg - i > 1 && beg - i < MINRUN) + { + b = (int16_t)(tp[i] & mask); /*check short run */ + j = i + 1; + while ((tp[j++] & mask) == b) + if (j == beg) + { + *op++ = (uint8_t)(128 - 2 + j - i); + *op++ = (uint8_t)(b >> shft); + occ -= 2; + i = beg; + break; + } + } + while (i < beg) + { /* write out non-run */ + if ((j = beg - i) > 127) + j = 127; + if (occ < j + 3) + { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = (uint8_t)j; + occ--; + while (j--) + { + *op++ = (uint8_t)(tp[i++] >> shft & 0xff); + occ--; + } + } + if (rc >= MINRUN) + { /* write out run */ + *op++ = (uint8_t)(128 - 2 + rc); + *op++ = (uint8_t)(tp[beg] >> shft & 0xff); + occ -= 2; + } + else + rc = 0; + } + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + + return (1); } /* * Encode a row of 24-bit pixels. */ -static int -LogLuvEncode24(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int LogLuvEncode24(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "LogLuvEncode24"; - LogLuvState* sp = EncoderState(tif); - tmsize_t i; - tmsize_t npixels; - tmsize_t occ; - uint8_t* op; - uint32_t* tp; - - (void)s; - assert(s == 0); - assert(sp != NULL); - npixels = cc / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32_t*) bp; - else { - tp = (uint32_t*) sp->tbuf; - if(sp->tbuflen < npixels) { - TIFFErrorExtR(tif, module, - "Translation buffer too short"); - return (0); - } - (*sp->tfunc)(sp, bp, npixels); - } - /* write out encoded pixels */ - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (i = npixels; i--; ) { - if (occ < 3) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - *op++ = (uint8_t)(*tp >> 16); - *op++ = (uint8_t)(*tp >> 8 & 0xff); - *op++ = (uint8_t)(*tp++ & 0xff); - occ -= 3; - } - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - - return (1); + static const char module[] = "LogLuvEncode24"; + LogLuvState *sp = EncoderState(tif); + tmsize_t i; + tmsize_t npixels; + tmsize_t occ; + uint8_t *op; + uint32_t *tp; + + (void)s; + assert(s == 0); + assert(sp != NULL); + npixels = cc / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32_t *)bp; + else + { + tp = (uint32_t *)sp->tbuf; + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + (*sp->tfunc)(sp, bp, npixels); + } + /* write out encoded pixels */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (i = npixels; i--;) + { + if (occ < 3) + { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = (uint8_t)(*tp >> 16); + *op++ = (uint8_t)(*tp >> 8 & 0xff); + *op++ = (uint8_t)(*tp++ & 0xff); + occ -= 3; + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + + return (1); } /* * Encode a row of 32-bit pixels. */ -static int -LogLuvEncode32(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int LogLuvEncode32(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "LogLuvEncode32"; - LogLuvState* sp = EncoderState(tif); - int shft; - tmsize_t i; - tmsize_t j; - tmsize_t npixels; - uint8_t* op; - uint32_t* tp; - uint32_t b; - tmsize_t occ; - int rc=0; - tmsize_t beg; - - (void)s; - assert(s == 0); - assert(sp != NULL); - - npixels = cc / sp->pixel_size; - - if (sp->user_datafmt == SGILOGDATAFMT_RAW) - tp = (uint32_t*) bp; - else { - tp = (uint32_t*) sp->tbuf; - if(sp->tbuflen < npixels) { - TIFFErrorExtR(tif, module, - "Translation buffer too short"); - return (0); - } - (*sp->tfunc)(sp, bp, npixels); - } - /* compress each byte string */ - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - for (shft = 24; shft >= 0; shft -=8) { - const uint32_t mask = 0xffU << shft; /* find next run */ - for (i = 0; i < npixels; i += rc) { - if (occ < 4) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - for (beg = i; beg < npixels; beg += rc) { - b = tp[beg] & mask; - rc = 1; - while (rc < 127+2 && beg+rc < npixels && - (tp[beg+rc] & mask) == b) - rc++; - if (rc >= MINRUN) - break; /* long enough */ - } - if (beg-i > 1 && beg-i < MINRUN) { - b = tp[i] & mask; /* check short run */ - j = i+1; - while ((tp[j++] & mask) == b) - if (j == beg) { - *op++ = (uint8_t)(128 - 2 + j - i); - *op++ = (uint8_t)(b >> shft); - occ -= 2; - i = beg; - break; - } - } - while (i < beg) { /* write out non-run */ - if ((j = beg-i) > 127) j = 127; - if (occ < j+3) { - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - occ = tif->tif_rawdatasize - tif->tif_rawcc; - } - *op++ = (uint8_t) j; occ--; - while (j--) { - *op++ = (uint8_t)(tp[i++] >> shft & 0xff); - occ--; - } - } - if (rc >= MINRUN) { /* write out run */ - *op++ = (uint8_t) (128 - 2 + rc); - *op++ = (uint8_t)(tp[beg] >> shft & 0xff); - occ -= 2; - } else - rc = 0; - } - } - tif->tif_rawcp = op; - tif->tif_rawcc = tif->tif_rawdatasize - occ; - - return (1); + static const char module[] = "LogLuvEncode32"; + LogLuvState *sp = EncoderState(tif); + int shft; + tmsize_t i; + tmsize_t j; + tmsize_t npixels; + uint8_t *op; + uint32_t *tp; + uint32_t b; + tmsize_t occ; + int rc = 0; + tmsize_t beg; + + (void)s; + assert(s == 0); + assert(sp != NULL); + + npixels = cc / sp->pixel_size; + + if (sp->user_datafmt == SGILOGDATAFMT_RAW) + tp = (uint32_t *)bp; + else + { + tp = (uint32_t *)sp->tbuf; + if (sp->tbuflen < npixels) + { + TIFFErrorExtR(tif, module, "Translation buffer too short"); + return (0); + } + (*sp->tfunc)(sp, bp, npixels); + } + /* compress each byte string */ + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + for (shft = 24; shft >= 0; shft -= 8) + { + const uint32_t mask = 0xffU << shft; /* find next run */ + for (i = 0; i < npixels; i += rc) + { + if (occ < 4) + { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + for (beg = i; beg < npixels; beg += rc) + { + b = tp[beg] & mask; + rc = 1; + while (rc < 127 + 2 && beg + rc < npixels && + (tp[beg + rc] & mask) == b) + rc++; + if (rc >= MINRUN) + break; /* long enough */ + } + if (beg - i > 1 && beg - i < MINRUN) + { + b = tp[i] & mask; /* check short run */ + j = i + 1; + while ((tp[j++] & mask) == b) + if (j == beg) + { + *op++ = (uint8_t)(128 - 2 + j - i); + *op++ = (uint8_t)(b >> shft); + occ -= 2; + i = beg; + break; + } + } + while (i < beg) + { /* write out non-run */ + if ((j = beg - i) > 127) + j = 127; + if (occ < j + 3) + { + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + occ = tif->tif_rawdatasize - tif->tif_rawcc; + } + *op++ = (uint8_t)j; + occ--; + while (j--) + { + *op++ = (uint8_t)(tp[i++] >> shft & 0xff); + occ--; + } + } + if (rc >= MINRUN) + { /* write out run */ + *op++ = (uint8_t)(128 - 2 + rc); + *op++ = (uint8_t)(tp[beg] >> shft & 0xff); + occ -= 2; + } + else + rc = 0; + } + } + tif->tif_rawcp = op; + tif->tif_rawcc = tif->tif_rawdatasize - occ; + + return (1); } /* * Encode a strip of pixels. We break it into rows to * avoid encoding runs across row boundaries. */ -static int -LogLuvEncodeStrip(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int LogLuvEncodeStrip(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - tmsize_t rowlen = TIFFScanlineSize(tif); - - if (rowlen == 0) - return 0; - - assert(cc%rowlen == 0); - while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); + tmsize_t rowlen = TIFFScanlineSize(tif); + + if (rowlen == 0) + return 0; + + assert(cc % rowlen == 0); + while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) + { + bp += rowlen; + cc -= rowlen; + } + return (cc == 0); } /* * Encode a tile of pixels. We break it into rows to * avoid encoding runs across row boundaries. */ -static int -LogLuvEncodeTile(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int LogLuvEncodeTile(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - tmsize_t rowlen = TIFFTileRowSize(tif); - - if (rowlen == 0) - return 0; - - assert(cc%rowlen == 0); - while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) { - bp += rowlen; - cc -= rowlen; - } - return (cc == 0); + tmsize_t rowlen = TIFFTileRowSize(tif); + + if (rowlen == 0) + return 0; + + assert(cc % rowlen == 0); + while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1) + { + bp += rowlen; + cc -= rowlen; + } + return (cc == 0); } /* @@ -711,190 +754,192 @@ LogLuvEncodeTile(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) #include "uvcode.h" #ifndef UVSCALE -#define U_NEU 0.210526316 -#define V_NEU 0.473684211 -#define UVSCALE 410. +#define U_NEU 0.210526316 +#define V_NEU 0.473684211 +#define UVSCALE 410. #endif -#ifndef M_LN2 -#define M_LN2 0.69314718055994530942 +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 #endif #ifndef M_PI -#define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif #undef log2 /* Conflict with C'99 function */ -#define log2(x) ((1./M_LN2)*log(x)) -#undef exp2 /* Conflict with C'99 function */ -#define exp2(x) exp(M_LN2*(x)) +#define log2(x) ((1. / M_LN2) * log(x)) +#undef exp2 /* Conflict with C'99 function */ +#define exp2(x) exp(M_LN2 *(x)) static int tiff_itrunc(double x, int m) { - if( m == SGILOGENCODE_NODITHER ) + if (m == SGILOGENCODE_NODITHER) return (int)x; /* Silence CoverityScan warning about bad crypto function */ /* coverity[dont_call] */ - return (int)(x + rand()*(1./RAND_MAX) - .5); + return (int)(x + rand() * (1. / RAND_MAX) - .5); } #if !LOGLUV_PUBLIC static #endif -double -LogL16toY(int p16) /* compute luminance from 16-bit LogL */ + double + LogL16toY(int p16) /* compute luminance from 16-bit LogL */ { - int Le = p16 & 0x7fff; - double Y; + int Le = p16 & 0x7fff; + double Y; - if (!Le) - return (0.); - Y = exp(M_LN2/256.*(Le+.5) - M_LN2*64.); - return (!(p16 & 0x8000) ? Y : -Y); + if (!Le) + return (0.); + Y = exp(M_LN2 / 256. * (Le + .5) - M_LN2 * 64.); + return (!(p16 & 0x8000) ? Y : -Y); } #if !LOGLUV_PUBLIC static #endif -int -LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */ + int + LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */ { - if (Y >= 1.8371976e19) - return (0x7fff); - if (Y <= -1.8371976e19) - return (0xffff); - if (Y > 5.4136769e-20) - return tiff_itrunc(256.*(log2(Y) + 64.), em); - if (Y < -5.4136769e-20) - return (~0x7fff | tiff_itrunc(256.*(log2(-Y) + 64.), em)); - return (0); + if (Y >= 1.8371976e19) + return (0x7fff); + if (Y <= -1.8371976e19) + return (0xffff); + if (Y > 5.4136769e-20) + return tiff_itrunc(256. * (log2(Y) + 64.), em); + if (Y < -5.4136769e-20) + return (~0x7fff | tiff_itrunc(256. * (log2(-Y) + 64.), em)); + return (0); } -static void -L16toY(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void L16toY(LogLuvState *sp, uint8_t *op, tmsize_t n) { - int16_t* l16 = (int16_t*) sp->tbuf; - float* yp = (float*) op; + int16_t *l16 = (int16_t *)sp->tbuf; + float *yp = (float *)op; - while (n-- > 0) - *yp++ = (float)LogL16toY(*l16++); + while (n-- > 0) + *yp++ = (float)LogL16toY(*l16++); } -static void -L16toGry(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void L16toGry(LogLuvState *sp, uint8_t *op, tmsize_t n) { - int16_t* l16 = (int16_t*) sp->tbuf; - uint8_t* gp = (uint8_t*) op; - - while (n-- > 0) { - double Y = LogL16toY(*l16++); - *gp++ = (uint8_t) ((Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256. * sqrt(Y))); - } + int16_t *l16 = (int16_t *)sp->tbuf; + uint8_t *gp = (uint8_t *)op; + + while (n-- > 0) + { + double Y = LogL16toY(*l16++); + *gp++ = (uint8_t)((Y <= 0.) ? 0 + : (Y >= 1.) ? 255 + : (int)(256. * sqrt(Y))); + } } -static void -L16fromY(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void L16fromY(LogLuvState *sp, uint8_t *op, tmsize_t n) { - int16_t* l16 = (int16_t*) sp->tbuf; - float* yp = (float*) op; + int16_t *l16 = (int16_t *)sp->tbuf; + float *yp = (float *)op; - while (n-- > 0) - *l16++ = (int16_t) (LogL16fromY(*yp++, sp->encode_meth)); + while (n-- > 0) + *l16++ = (int16_t)(LogL16fromY(*yp++, sp->encode_meth)); } #if !LOGLUV_PUBLIC static #endif -void -XYZtoRGB24(float* xyz, uint8_t* rgb) + void + XYZtoRGB24(float *xyz, uint8_t *rgb) { - double r, g, b; - /* assume CCIR-709 primaries */ - r = 2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2]; - g = -1.022*xyz[0] + 1.978*xyz[1] + 0.044*xyz[2]; - b = 0.061*xyz[0] + -0.224*xyz[1] + 1.163*xyz[2]; - /* assume 2.0 gamma for speed */ - /* could use integer sqrt approx., but this is probably faster */ - rgb[0] = (uint8_t)((r <= 0.) ? 0 : (r >= 1.) ? 255 : (int)(256. * sqrt(r))); - rgb[1] = (uint8_t)((g <= 0.) ? 0 : (g >= 1.) ? 255 : (int)(256. * sqrt(g))); - rgb[2] = (uint8_t)((b <= 0.) ? 0 : (b >= 1.) ? 255 : (int)(256. * sqrt(b))); + double r, g, b; + /* assume CCIR-709 primaries */ + r = 2.690 * xyz[0] + -1.276 * xyz[1] + -0.414 * xyz[2]; + g = -1.022 * xyz[0] + 1.978 * xyz[1] + 0.044 * xyz[2]; + b = 0.061 * xyz[0] + -0.224 * xyz[1] + 1.163 * xyz[2]; + /* assume 2.0 gamma for speed */ + /* could use integer sqrt approx., but this is probably faster */ + rgb[0] = (uint8_t)((r <= 0.) ? 0 : (r >= 1.) ? 255 : (int)(256. * sqrt(r))); + rgb[1] = (uint8_t)((g <= 0.) ? 0 : (g >= 1.) ? 255 : (int)(256. * sqrt(g))); + rgb[2] = (uint8_t)((b <= 0.) ? 0 : (b >= 1.) ? 255 : (int)(256. * sqrt(b))); } #if !LOGLUV_PUBLIC static #endif -double -LogL10toY(int p10) /* compute luminance from 10-bit LogL */ + double + LogL10toY(int p10) /* compute luminance from 10-bit LogL */ { - if (p10 == 0) - return (0.); - return (exp(M_LN2/64.*(p10+.5) - M_LN2*12.)); + if (p10 == 0) + return (0.); + return (exp(M_LN2 / 64. * (p10 + .5) - M_LN2 * 12.)); } #if !LOGLUV_PUBLIC static #endif -int -LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */ + int + LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */ { - if (Y >= 15.742) - return (0x3ff); - else if (Y <= .00024283) - return (0); - else - return tiff_itrunc(64.*(log2(Y) + 12.), em); + if (Y >= 15.742) + return (0x3ff); + else if (Y <= .00024283) + return (0); + else + return tiff_itrunc(64. * (log2(Y) + 12.), em); } -#define NANGLES 100 -#define uv2ang(u, v) ( (NANGLES*.499999999/M_PI) \ - * atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES ) +#define NANGLES 100 +#define uv2ang(u, v) \ + ((NANGLES * .499999999 / M_PI) * atan2((v)-V_NEU, (u)-U_NEU) + .5 * NANGLES) -static int -oog_encode(double u, double v) /* encode out-of-gamut chroma */ +static int oog_encode(double u, double v) /* encode out-of-gamut chroma */ { - static int oog_table[NANGLES]; - static int initialized = 0; - register int i; - - if (!initialized) { /* set up perimeter table */ - double eps[NANGLES], ua, va, ang, epsa; - int ui, vi, ustep; - for (i = NANGLES; i--; ) - eps[i] = 2.; - for (vi = UV_NVS; vi--; ) { - va = UV_VSTART + (vi+.5)*UV_SQSIZ; - ustep = uv_row[vi].nus-1; - if (vi == UV_NVS-1 || vi == 0 || ustep <= 0) - ustep = 1; - for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) { - ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ; - ang = uv2ang(ua, va); - i = (int) ang; - epsa = fabs(ang - (i+.5)); - if (epsa < eps[i]) { - oog_table[i] = uv_row[vi].ncum + ui; - eps[i] = epsa; - } - } - } - for (i = NANGLES; i--; ) /* fill any holes */ - if (eps[i] > 1.5) { - int i1, i2; - for (i1 = 1; i1 < NANGLES/2; i1++) - if (eps[(i+i1)%NANGLES] < 1.5) - break; - for (i2 = 1; i2 < NANGLES/2; i2++) - if (eps[(i+NANGLES-i2)%NANGLES] < 1.5) - break; - if (i1 < i2) - oog_table[i] = - oog_table[(i+i1)%NANGLES]; - else - oog_table[i] = - oog_table[(i+NANGLES-i2)%NANGLES]; - } - initialized = 1; - } - i = (int) uv2ang(u, v); /* look up hue angle */ - return (oog_table[i]); + static int oog_table[NANGLES]; + static int initialized = 0; + register int i; + + if (!initialized) + { /* set up perimeter table */ + double eps[NANGLES], ua, va, ang, epsa; + int ui, vi, ustep; + for (i = NANGLES; i--;) + eps[i] = 2.; + for (vi = UV_NVS; vi--;) + { + va = UV_VSTART + (vi + .5) * UV_SQSIZ; + ustep = uv_row[vi].nus - 1; + if (vi == UV_NVS - 1 || vi == 0 || ustep <= 0) + ustep = 1; + for (ui = uv_row[vi].nus - 1; ui >= 0; ui -= ustep) + { + ua = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ; + ang = uv2ang(ua, va); + i = (int)ang; + epsa = fabs(ang - (i + .5)); + if (epsa < eps[i]) + { + oog_table[i] = uv_row[vi].ncum + ui; + eps[i] = epsa; + } + } + } + for (i = NANGLES; i--;) /* fill any holes */ + if (eps[i] > 1.5) + { + int i1, i2; + for (i1 = 1; i1 < NANGLES / 2; i1++) + if (eps[(i + i1) % NANGLES] < 1.5) + break; + for (i2 = 1; i2 < NANGLES / 2; i2++) + if (eps[(i + NANGLES - i2) % NANGLES] < 1.5) + break; + if (i1 < i2) + oog_table[i] = oog_table[(i + i1) % NANGLES]; + else + oog_table[i] = oog_table[(i + NANGLES - i2) % NANGLES]; + } + initialized = 1; + } + i = (int)uv2ang(u, v); /* look up hue angle */ + return (oog_table[i]); } #undef uv2ang @@ -903,838 +948,884 @@ oog_encode(double u, double v) /* encode out-of-gamut chroma */ #if !LOGLUV_PUBLIC static #endif -int -uv_encode(double u, double v, int em) /* encode (u',v') coordinates */ + int + uv_encode(double u, double v, int em) /* encode (u',v') coordinates */ { - register int vi, ui; - - if (v < UV_VSTART) - return oog_encode(u, v); - vi = tiff_itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em); - if (vi >= UV_NVS) - return oog_encode(u, v); - if (u < uv_row[vi].ustart) - return oog_encode(u, v); - ui = tiff_itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em); - if (ui >= uv_row[vi].nus) - return oog_encode(u, v); - - return (uv_row[vi].ncum + ui); + register int vi, ui; + + if (v < UV_VSTART) + return oog_encode(u, v); + vi = tiff_itrunc((v - UV_VSTART) * (1. / UV_SQSIZ), em); + if (vi >= UV_NVS) + return oog_encode(u, v); + if (u < uv_row[vi].ustart) + return oog_encode(u, v); + ui = tiff_itrunc((u - uv_row[vi].ustart) * (1. / UV_SQSIZ), em); + if (ui >= uv_row[vi].nus) + return oog_encode(u, v); + + return (uv_row[vi].ncum + ui); } #if !LOGLUV_PUBLIC static #endif -int -uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ + int + uv_decode(double *up, double *vp, int c) /* decode (u',v') index */ { - int upper, lower; - register int ui, vi; - - if (c < 0 || c >= UV_NDIVS) - return (-1); - lower = 0; /* binary search */ - upper = UV_NVS; - while (upper - lower > 1) { - vi = (lower + upper) >> 1; - ui = c - uv_row[vi].ncum; - if (ui > 0) - lower = vi; - else if (ui < 0) - upper = vi; - else { - lower = vi; - break; - } - } - vi = lower; - ui = c - uv_row[vi].ncum; - *up = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ; - *vp = UV_VSTART + (vi+.5)*UV_SQSIZ; - return (0); + int upper, lower; + register int ui, vi; + + if (c < 0 || c >= UV_NDIVS) + return (-1); + lower = 0; /* binary search */ + upper = UV_NVS; + while (upper - lower > 1) + { + vi = (lower + upper) >> 1; + ui = c - uv_row[vi].ncum; + if (ui > 0) + lower = vi; + else if (ui < 0) + upper = vi; + else + { + lower = vi; + break; + } + } + vi = lower; + ui = c - uv_row[vi].ncum; + *up = uv_row[vi].ustart + (ui + .5) * UV_SQSIZ; + *vp = UV_VSTART + (vi + .5) * UV_SQSIZ; + return (0); } #if !LOGLUV_PUBLIC static #endif -void -LogLuv24toXYZ(uint32_t p, float* XYZ) + void + LogLuv24toXYZ(uint32_t p, float *XYZ) { - int Ce; - double L, u, v, s, x, y; - /* decode luminance */ - L = LogL10toY(p>>14 & 0x3ff); - if (L <= 0.) { - XYZ[0] = XYZ[1] = XYZ[2] = 0.; - return; - } - /* decode color */ - Ce = p & 0x3fff; - if (uv_decode(&u, &v, Ce) < 0) { - u = U_NEU; v = V_NEU; - } - s = 1./(6.*u - 16.*v + 12.); - x = 9.*u * s; - y = 4.*v * s; - /* convert to XYZ */ - XYZ[0] = (float)(x/y * L); - XYZ[1] = (float)L; - XYZ[2] = (float)((1.-x-y)/y * L); + int Ce; + double L, u, v, s, x, y; + /* decode luminance */ + L = LogL10toY(p >> 14 & 0x3ff); + if (L <= 0.) + { + XYZ[0] = XYZ[1] = XYZ[2] = 0.; + return; + } + /* decode color */ + Ce = p & 0x3fff; + if (uv_decode(&u, &v, Ce) < 0) + { + u = U_NEU; + v = V_NEU; + } + s = 1. / (6. * u - 16. * v + 12.); + x = 9. * u * s; + y = 4. * v * s; + /* convert to XYZ */ + XYZ[0] = (float)(x / y * L); + XYZ[1] = (float)L; + XYZ[2] = (float)((1. - x - y) / y * L); } #if !LOGLUV_PUBLIC static #endif -uint32_t -LogLuv24fromXYZ(float* XYZ, int em) + uint32_t + LogLuv24fromXYZ(float *XYZ, int em) { - int Le, Ce; - double u, v, s; - /* encode luminance */ - Le = LogL10fromY(XYZ[1], em); - /* encode color */ - s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2]; - if (!Le || s <= 0.) { - u = U_NEU; - v = V_NEU; - } else { - u = 4.*XYZ[0] / s; - v = 9.*XYZ[1] / s; - } - Ce = uv_encode(u, v, em); - if (Ce < 0) /* never happens */ - Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); - /* combine encodings */ - return (Le << 14 | Ce); + int Le, Ce; + double u, v, s; + /* encode luminance */ + Le = LogL10fromY(XYZ[1], em); + /* encode color */ + s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2]; + if (!Le || s <= 0.) + { + u = U_NEU; + v = V_NEU; + } + else + { + u = 4. * XYZ[0] / s; + v = 9. * XYZ[1] / s; + } + Ce = uv_encode(u, v, em); + if (Ce < 0) /* never happens */ + Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); + /* combine encodings */ + return (Le << 14 | Ce); } -static void -Luv24toXYZ(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void Luv24toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) { - uint32_t* luv = (uint32_t*) sp->tbuf; - float* xyz = (float*) op; - - while (n-- > 0) { - LogLuv24toXYZ(*luv, xyz); - xyz += 3; - luv++; - } + uint32_t *luv = (uint32_t *)sp->tbuf; + float *xyz = (float *)op; + + while (n-- > 0) + { + LogLuv24toXYZ(*luv, xyz); + xyz += 3; + luv++; + } } -static void -Luv24toLuv48(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void Luv24toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) { - uint32_t* luv = (uint32_t*) sp->tbuf; - int16_t* luv3 = (int16_t*) op; - - while (n-- > 0) { - double u, v; - - *luv3++ = (int16_t)((*luv >> 12 & 0xffd) + 13314); - if (uv_decode(&u, &v, *luv&0x3fff) < 0) { - u = U_NEU; - v = V_NEU; - } - *luv3++ = (int16_t)(u * (1L << 15)); - *luv3++ = (int16_t)(v * (1L << 15)); - luv++; - } + uint32_t *luv = (uint32_t *)sp->tbuf; + int16_t *luv3 = (int16_t *)op; + + while (n-- > 0) + { + double u, v; + + *luv3++ = (int16_t)((*luv >> 12 & 0xffd) + 13314); + if (uv_decode(&u, &v, *luv & 0x3fff) < 0) + { + u = U_NEU; + v = V_NEU; + } + *luv3++ = (int16_t)(u * (1L << 15)); + *luv3++ = (int16_t)(v * (1L << 15)); + luv++; + } } -static void -Luv24toRGB(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void Luv24toRGB(LogLuvState *sp, uint8_t *op, tmsize_t n) { - uint32_t* luv = (uint32_t*) sp->tbuf; - uint8_t* rgb = (uint8_t*) op; + uint32_t *luv = (uint32_t *)sp->tbuf; + uint8_t *rgb = (uint8_t *)op; - while (n-- > 0) { - float xyz[3]; + while (n-- > 0) + { + float xyz[3]; - LogLuv24toXYZ(*luv++, xyz); - XYZtoRGB24(xyz, rgb); - rgb += 3; - } + LogLuv24toXYZ(*luv++, xyz); + XYZtoRGB24(xyz, rgb); + rgb += 3; + } } -static void -Luv24fromXYZ(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void Luv24fromXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) { - uint32_t* luv = (uint32_t*) sp->tbuf; - float* xyz = (float*) op; - - while (n-- > 0) { - *luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth); - xyz += 3; - } + uint32_t *luv = (uint32_t *)sp->tbuf; + float *xyz = (float *)op; + + while (n-- > 0) + { + *luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth); + xyz += 3; + } } -static void -Luv24fromLuv48(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void Luv24fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) { - uint32_t* luv = (uint32_t*) sp->tbuf; - int16_t* luv3 = (int16_t*) op; - - while (n-- > 0) { - int Le, Ce; - - if (luv3[0] <= 0) - Le = 0; - else if (luv3[0] >= (1<<12)+3314) - Le = (1<<10) - 1; - else if (sp->encode_meth == SGILOGENCODE_NODITHER) - Le = (luv3[0]-3314) >> 2; - else - Le = tiff_itrunc(.25*(luv3[0]-3314.), sp->encode_meth); - - Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15), - sp->encode_meth); - if (Ce < 0) /* never happens */ - Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); - *luv++ = (uint32_t)Le << 14 | Ce; - luv3 += 3; - } + uint32_t *luv = (uint32_t *)sp->tbuf; + int16_t *luv3 = (int16_t *)op; + + while (n-- > 0) + { + int Le, Ce; + + if (luv3[0] <= 0) + Le = 0; + else if (luv3[0] >= (1 << 12) + 3314) + Le = (1 << 10) - 1; + else if (sp->encode_meth == SGILOGENCODE_NODITHER) + Le = (luv3[0] - 3314) >> 2; + else + Le = tiff_itrunc(.25 * (luv3[0] - 3314.), sp->encode_meth); + + Ce = uv_encode((luv3[1] + .5) / (1 << 15), (luv3[2] + .5) / (1 << 15), + sp->encode_meth); + if (Ce < 0) /* never happens */ + Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER); + *luv++ = (uint32_t)Le << 14 | Ce; + luv3 += 3; + } } #if !LOGLUV_PUBLIC static #endif -void -LogLuv32toXYZ(uint32_t p, float* XYZ) + void + LogLuv32toXYZ(uint32_t p, float *XYZ) { - double L, u, v, s, x, y; - /* decode luminance */ - L = LogL16toY((int)p >> 16); - if (L <= 0.) { - XYZ[0] = XYZ[1] = XYZ[2] = 0.; - return; - } - /* decode color */ - u = 1./UVSCALE * ((p>>8 & 0xff) + .5); - v = 1./UVSCALE * ((p & 0xff) + .5); - s = 1./(6.*u - 16.*v + 12.); - x = 9.*u * s; - y = 4.*v * s; - /* convert to XYZ */ - XYZ[0] = (float)(x/y * L); - XYZ[1] = (float)L; - XYZ[2] = (float)((1.-x-y)/y * L); + double L, u, v, s, x, y; + /* decode luminance */ + L = LogL16toY((int)p >> 16); + if (L <= 0.) + { + XYZ[0] = XYZ[1] = XYZ[2] = 0.; + return; + } + /* decode color */ + u = 1. / UVSCALE * ((p >> 8 & 0xff) + .5); + v = 1. / UVSCALE * ((p & 0xff) + .5); + s = 1. / (6. * u - 16. * v + 12.); + x = 9. * u * s; + y = 4. * v * s; + /* convert to XYZ */ + XYZ[0] = (float)(x / y * L); + XYZ[1] = (float)L; + XYZ[2] = (float)((1. - x - y) / y * L); } #if !LOGLUV_PUBLIC static #endif -uint32_t -LogLuv32fromXYZ(float* XYZ, int em) + uint32_t + LogLuv32fromXYZ(float *XYZ, int em) { - unsigned int Le, ue, ve; - double u, v, s; - /* encode luminance */ - Le = (unsigned int)LogL16fromY(XYZ[1], em); - /* encode color */ - s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2]; - if (!Le || s <= 0.) { - u = U_NEU; - v = V_NEU; - } else { - u = 4.*XYZ[0] / s; - v = 9.*XYZ[1] / s; - } - if (u <= 0.) ue = 0; - else ue = tiff_itrunc(UVSCALE*u, em); - if (ue > 255) ue = 255; - if (v <= 0.) ve = 0; - else ve = tiff_itrunc(UVSCALE*v, em); - if (ve > 255) ve = 255; - /* combine encodings */ - return (Le << 16 | ue << 8 | ve); + unsigned int Le, ue, ve; + double u, v, s; + /* encode luminance */ + Le = (unsigned int)LogL16fromY(XYZ[1], em); + /* encode color */ + s = XYZ[0] + 15. * XYZ[1] + 3. * XYZ[2]; + if (!Le || s <= 0.) + { + u = U_NEU; + v = V_NEU; + } + else + { + u = 4. * XYZ[0] / s; + v = 9. * XYZ[1] / s; + } + if (u <= 0.) + ue = 0; + else + ue = tiff_itrunc(UVSCALE * u, em); + if (ue > 255) + ue = 255; + if (v <= 0.) + ve = 0; + else + ve = tiff_itrunc(UVSCALE * v, em); + if (ve > 255) + ve = 255; + /* combine encodings */ + return (Le << 16 | ue << 8 | ve); } -static void -Luv32toXYZ(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void Luv32toXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) { - uint32_t* luv = (uint32_t*) sp->tbuf; - float* xyz = (float*) op; - - while (n-- > 0) { - LogLuv32toXYZ(*luv++, xyz); - xyz += 3; - } + uint32_t *luv = (uint32_t *)sp->tbuf; + float *xyz = (float *)op; + + while (n-- > 0) + { + LogLuv32toXYZ(*luv++, xyz); + xyz += 3; + } } -static void -Luv32toLuv48(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void Luv32toLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) { - uint32_t* luv = (uint32_t*) sp->tbuf; - int16_t* luv3 = (int16_t*) op; - - while (n-- > 0) { - double u, v; - - *luv3++ = (int16_t)(*luv >> 16); - u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5); - v = 1./UVSCALE * ((*luv & 0xff) + .5); - *luv3++ = (int16_t)(u * (1L << 15)); - *luv3++ = (int16_t)(v * (1L << 15)); - luv++; - } + uint32_t *luv = (uint32_t *)sp->tbuf; + int16_t *luv3 = (int16_t *)op; + + while (n-- > 0) + { + double u, v; + + *luv3++ = (int16_t)(*luv >> 16); + u = 1. / UVSCALE * ((*luv >> 8 & 0xff) + .5); + v = 1. / UVSCALE * ((*luv & 0xff) + .5); + *luv3++ = (int16_t)(u * (1L << 15)); + *luv3++ = (int16_t)(v * (1L << 15)); + luv++; + } } -static void -Luv32toRGB(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void Luv32toRGB(LogLuvState *sp, uint8_t *op, tmsize_t n) { - uint32_t* luv = (uint32_t*) sp->tbuf; - uint8_t* rgb = (uint8_t*) op; + uint32_t *luv = (uint32_t *)sp->tbuf; + uint8_t *rgb = (uint8_t *)op; - while (n-- > 0) { - float xyz[3]; + while (n-- > 0) + { + float xyz[3]; - LogLuv32toXYZ(*luv++, xyz); - XYZtoRGB24(xyz, rgb); - rgb += 3; - } + LogLuv32toXYZ(*luv++, xyz); + XYZtoRGB24(xyz, rgb); + rgb += 3; + } } -static void -Luv32fromXYZ(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void Luv32fromXYZ(LogLuvState *sp, uint8_t *op, tmsize_t n) { - uint32_t* luv = (uint32_t*) sp->tbuf; - float* xyz = (float*) op; - - while (n-- > 0) { - *luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth); - xyz += 3; - } + uint32_t *luv = (uint32_t *)sp->tbuf; + float *xyz = (float *)op; + + while (n-- > 0) + { + *luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth); + xyz += 3; + } } -static void -Luv32fromLuv48(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void Luv32fromLuv48(LogLuvState *sp, uint8_t *op, tmsize_t n) { - uint32_t* luv = (uint32_t*) sp->tbuf; - int16_t* luv3 = (int16_t*) op; - - if (sp->encode_meth == SGILOGENCODE_NODITHER) { - while (n-- > 0) { - *luv++ = (uint32_t)luv3[0] << 16 | - (luv3[1]*(uint32_t)(UVSCALE + .5) >> 7 & 0xff00) | - (luv3[2]*(uint32_t)(UVSCALE + .5) >> 15 & 0xff); - luv3 += 3; - } - return; - } - while (n-- > 0) { - *luv++ = (uint32_t)luv3[0] << 16 | - (tiff_itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) | - (tiff_itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff); - luv3 += 3; - } + uint32_t *luv = (uint32_t *)sp->tbuf; + int16_t *luv3 = (int16_t *)op; + + if (sp->encode_meth == SGILOGENCODE_NODITHER) + { + while (n-- > 0) + { + *luv++ = (uint32_t)luv3[0] << 16 | + (luv3[1] * (uint32_t)(UVSCALE + .5) >> 7 & 0xff00) | + (luv3[2] * (uint32_t)(UVSCALE + .5) >> 15 & 0xff); + luv3 += 3; + } + return; + } + while (n-- > 0) + { + *luv++ = + (uint32_t)luv3[0] << 16 | + (tiff_itrunc(luv3[1] * (UVSCALE / (1 << 15)), sp->encode_meth) + << 8 & + 0xff00) | + (tiff_itrunc(luv3[2] * (UVSCALE / (1 << 15)), sp->encode_meth) & + 0xff); + luv3 += 3; + } } -static void -_logLuvNop(LogLuvState* sp, uint8_t* op, tmsize_t n) +static void _logLuvNop(LogLuvState *sp, uint8_t *op, tmsize_t n) { - (void) sp; (void) op; (void) n; + (void)sp; + (void)op; + (void)n; } -static int -LogL16GuessDataFmt(TIFFDirectory *td) +static int LogL16GuessDataFmt(TIFFDirectory *td) { -#define PACK(s,b,f) (((b)<<6)|((s)<<3)|(f)) - switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) { - case PACK(1, 32, SAMPLEFORMAT_IEEEFP): - return (SGILOGDATAFMT_FLOAT); - case PACK(1, 16, SAMPLEFORMAT_VOID): - case PACK(1, 16, SAMPLEFORMAT_INT): - case PACK(1, 16, SAMPLEFORMAT_UINT): - return (SGILOGDATAFMT_16BIT); - case PACK(1, 8, SAMPLEFORMAT_VOID): - case PACK(1, 8, SAMPLEFORMAT_UINT): - return (SGILOGDATAFMT_8BIT); - } +#define PACK(s, b, f) (((b) << 6) | ((s) << 3) | (f)) + switch ( + PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) + { + case PACK(1, 32, SAMPLEFORMAT_IEEEFP): + return (SGILOGDATAFMT_FLOAT); + case PACK(1, 16, SAMPLEFORMAT_VOID): + case PACK(1, 16, SAMPLEFORMAT_INT): + case PACK(1, 16, SAMPLEFORMAT_UINT): + return (SGILOGDATAFMT_16BIT); + case PACK(1, 8, SAMPLEFORMAT_VOID): + case PACK(1, 8, SAMPLEFORMAT_UINT): + return (SGILOGDATAFMT_8BIT); + } #undef PACK - return (SGILOGDATAFMT_UNKNOWN); + return (SGILOGDATAFMT_UNKNOWN); } -static tmsize_t -multiply_ms(tmsize_t m1, tmsize_t m2) +static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) { - return _TIFFMultiplySSize(NULL, m1, m2, NULL); + return _TIFFMultiplySSize(NULL, m1, m2, NULL); } -static int -LogL16InitState(TIFF* tif) +static int LogL16InitState(TIFF *tif) { - static const char module[] = "LogL16InitState"; - TIFFDirectory *td = &tif->tif_dir; - LogLuvState* sp = DecoderState(tif); - - assert(sp != NULL); - assert(td->td_photometric == PHOTOMETRIC_LOGL); - - if( td->td_samplesperpixel != 1 ) - { - TIFFErrorExtR(tif, module, - "Sorry, can not handle LogL image with %s=%"PRIu16, - "Samples/pixel", td->td_samplesperpixel); - return 0; - } - - /* for some reason, we can't do this in TIFFInitLogL16 */ - if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) - sp->user_datafmt = LogL16GuessDataFmt(td); - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->pixel_size = sizeof (float); - break; - case SGILOGDATAFMT_16BIT: - sp->pixel_size = sizeof (int16_t); - break; - case SGILOGDATAFMT_8BIT: - sp->pixel_size = sizeof (uint8_t); - break; - default: - TIFFErrorExtR(tif, module, - "No support for converting user data format to LogL"); - return (0); - } - if( isTiled(tif) ) - sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); - else if( td->td_rowsperstrip < td->td_imagelength ) - sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); - else - sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); - if (multiply_ms(sp->tbuflen, sizeof (int16_t)) == 0 || - (sp->tbuf = (uint8_t*) _TIFFmallocExt(tif, sp->tbuflen * sizeof (int16_t))) == NULL) { - TIFFErrorExtR(tif, module, "No space for SGILog translation buffer"); - return (0); - } - return (1); + static const char module[] = "LogL16InitState"; + TIFFDirectory *td = &tif->tif_dir; + LogLuvState *sp = DecoderState(tif); + + assert(sp != NULL); + assert(td->td_photometric == PHOTOMETRIC_LOGL); + + if (td->td_samplesperpixel != 1) + { + TIFFErrorExtR(tif, module, + "Sorry, can not handle LogL image with %s=%" PRIu16, + "Samples/pixel", td->td_samplesperpixel); + return 0; + } + + /* for some reason, we can't do this in TIFFInitLogL16 */ + if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) + sp->user_datafmt = LogL16GuessDataFmt(td); + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->pixel_size = sizeof(float); + break; + case SGILOGDATAFMT_16BIT: + sp->pixel_size = sizeof(int16_t); + break; + case SGILOGDATAFMT_8BIT: + sp->pixel_size = sizeof(uint8_t); + break; + default: + TIFFErrorExtR(tif, module, + "No support for converting user data format to LogL"); + return (0); + } + if (isTiled(tif)) + sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); + else if (td->td_rowsperstrip < td->td_imagelength) + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + else + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); + if (multiply_ms(sp->tbuflen, sizeof(int16_t)) == 0 || + (sp->tbuf = (uint8_t *)_TIFFmallocExt( + tif, sp->tbuflen * sizeof(int16_t))) == NULL) + { + TIFFErrorExtR(tif, module, "No space for SGILog translation buffer"); + return (0); + } + return (1); } -static int -LogLuvGuessDataFmt(TIFFDirectory *td) +static int LogLuvGuessDataFmt(TIFFDirectory *td) { - int guess; - - /* - * If the user didn't tell us their datafmt, - * take our best guess from the bitspersample. - */ -#define PACK(a,b) (((a)<<3)|(b)) - switch (PACK(td->td_bitspersample, td->td_sampleformat)) { - case PACK(32, SAMPLEFORMAT_IEEEFP): - guess = SGILOGDATAFMT_FLOAT; - break; - case PACK(32, SAMPLEFORMAT_VOID): - case PACK(32, SAMPLEFORMAT_UINT): - case PACK(32, SAMPLEFORMAT_INT): - guess = SGILOGDATAFMT_RAW; - break; - case PACK(16, SAMPLEFORMAT_VOID): - case PACK(16, SAMPLEFORMAT_INT): - case PACK(16, SAMPLEFORMAT_UINT): - guess = SGILOGDATAFMT_16BIT; - break; - case PACK( 8, SAMPLEFORMAT_VOID): - case PACK( 8, SAMPLEFORMAT_UINT): - guess = SGILOGDATAFMT_8BIT; - break; - default: - guess = SGILOGDATAFMT_UNKNOWN; - break; + int guess; + + /* + * If the user didn't tell us their datafmt, + * take our best guess from the bitspersample. + */ +#define PACK(a, b) (((a) << 3) | (b)) + switch (PACK(td->td_bitspersample, td->td_sampleformat)) + { + case PACK(32, SAMPLEFORMAT_IEEEFP): + guess = SGILOGDATAFMT_FLOAT; + break; + case PACK(32, SAMPLEFORMAT_VOID): + case PACK(32, SAMPLEFORMAT_UINT): + case PACK(32, SAMPLEFORMAT_INT): + guess = SGILOGDATAFMT_RAW; + break; + case PACK(16, SAMPLEFORMAT_VOID): + case PACK(16, SAMPLEFORMAT_INT): + case PACK(16, SAMPLEFORMAT_UINT): + guess = SGILOGDATAFMT_16BIT; + break; + case PACK(8, SAMPLEFORMAT_VOID): + case PACK(8, SAMPLEFORMAT_UINT): + guess = SGILOGDATAFMT_8BIT; + break; + default: + guess = SGILOGDATAFMT_UNKNOWN; + break; #undef PACK - } - /* - * Double-check samples per pixel. - */ - switch (td->td_samplesperpixel) { - case 1: - if (guess != SGILOGDATAFMT_RAW) - guess = SGILOGDATAFMT_UNKNOWN; - break; - case 3: - if (guess == SGILOGDATAFMT_RAW) - guess = SGILOGDATAFMT_UNKNOWN; - break; - default: - guess = SGILOGDATAFMT_UNKNOWN; - break; - } - return (guess); + } + /* + * Double-check samples per pixel. + */ + switch (td->td_samplesperpixel) + { + case 1: + if (guess != SGILOGDATAFMT_RAW) + guess = SGILOGDATAFMT_UNKNOWN; + break; + case 3: + if (guess == SGILOGDATAFMT_RAW) + guess = SGILOGDATAFMT_UNKNOWN; + break; + default: + guess = SGILOGDATAFMT_UNKNOWN; + break; + } + return (guess); } -static int -LogLuvInitState(TIFF* tif) +static int LogLuvInitState(TIFF *tif) { - static const char module[] = "LogLuvInitState"; - TIFFDirectory* td = &tif->tif_dir; - LogLuvState* sp = DecoderState(tif); - - assert(sp != NULL); - assert(td->td_photometric == PHOTOMETRIC_LOGLUV); - - /* for some reason, we can't do this in TIFFInitLogLuv */ - if (td->td_planarconfig != PLANARCONFIG_CONTIG) { - TIFFErrorExtR(tif, module, - "SGILog compression cannot handle non-contiguous data"); - return (0); - } - if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) - sp->user_datafmt = LogLuvGuessDataFmt(td); - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->pixel_size = 3*sizeof (float); - break; - case SGILOGDATAFMT_16BIT: - sp->pixel_size = 3*sizeof (int16_t); - break; - case SGILOGDATAFMT_RAW: - sp->pixel_size = sizeof (uint32_t); - break; - case SGILOGDATAFMT_8BIT: - sp->pixel_size = 3*sizeof (uint8_t); - break; - default: - TIFFErrorExtR(tif, module, - "No support for converting user data format to LogLuv"); - return (0); - } - if( isTiled(tif) ) - sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); - else if( td->td_rowsperstrip < td->td_imagelength ) - sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); - else - sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); - if (multiply_ms(sp->tbuflen, sizeof (uint32_t)) == 0 || - (sp->tbuf = (uint8_t*) _TIFFmallocExt(tif, sp->tbuflen * sizeof (uint32_t))) == NULL) { - TIFFErrorExtR(tif, module, "No space for SGILog translation buffer"); - return (0); - } - return (1); + static const char module[] = "LogLuvInitState"; + TIFFDirectory *td = &tif->tif_dir; + LogLuvState *sp = DecoderState(tif); + + assert(sp != NULL); + assert(td->td_photometric == PHOTOMETRIC_LOGLUV); + + /* for some reason, we can't do this in TIFFInitLogLuv */ + if (td->td_planarconfig != PLANARCONFIG_CONTIG) + { + TIFFErrorExtR(tif, module, + "SGILog compression cannot handle non-contiguous data"); + return (0); + } + if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN) + sp->user_datafmt = LogLuvGuessDataFmt(td); + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->pixel_size = 3 * sizeof(float); + break; + case SGILOGDATAFMT_16BIT: + sp->pixel_size = 3 * sizeof(int16_t); + break; + case SGILOGDATAFMT_RAW: + sp->pixel_size = sizeof(uint32_t); + break; + case SGILOGDATAFMT_8BIT: + sp->pixel_size = 3 * sizeof(uint8_t); + break; + default: + TIFFErrorExtR( + tif, module, + "No support for converting user data format to LogLuv"); + return (0); + } + if (isTiled(tif)) + sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength); + else if (td->td_rowsperstrip < td->td_imagelength) + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip); + else + sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_imagelength); + if (multiply_ms(sp->tbuflen, sizeof(uint32_t)) == 0 || + (sp->tbuf = (uint8_t *)_TIFFmallocExt( + tif, sp->tbuflen * sizeof(uint32_t))) == NULL) + { + TIFFErrorExtR(tif, module, "No space for SGILog translation buffer"); + return (0); + } + return (1); } -static int -LogLuvFixupTags(TIFF* tif) +static int LogLuvFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } -static int -LogLuvSetupDecode(TIFF* tif) +static int LogLuvSetupDecode(TIFF *tif) { - static const char module[] = "LogLuvSetupDecode"; - LogLuvState* sp = DecoderState(tif); - TIFFDirectory* td = &tif->tif_dir; - - tif->tif_postdecode = _TIFFNoPostDecode; - switch (td->td_photometric) { - case PHOTOMETRIC_LOGLUV: - if (!LogLuvInitState(tif)) - break; - if (td->td_compression == COMPRESSION_SGILOG24) { - tif->tif_decoderow = LogLuvDecode24; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv24toXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv24toLuv48; - break; - case SGILOGDATAFMT_8BIT: - sp->tfunc = Luv24toRGB; - break; - } - } else { - tif->tif_decoderow = LogLuvDecode32; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv32toXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv32toLuv48; - break; - case SGILOGDATAFMT_8BIT: - sp->tfunc = Luv32toRGB; - break; - } - } - return (1); - case PHOTOMETRIC_LOGL: - if (!LogL16InitState(tif)) - break; - tif->tif_decoderow = LogL16Decode; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = L16toY; - break; - case SGILOGDATAFMT_8BIT: - sp->tfunc = L16toGry; - break; - } - return (1); - default: - TIFFErrorExtR(tif, module, - "Inappropriate photometric interpretation %"PRIu16" for SGILog compression; %s", - td->td_photometric, "must be either LogLUV or LogL"); - break; - } - return (0); + static const char module[] = "LogLuvSetupDecode"; + LogLuvState *sp = DecoderState(tif); + TIFFDirectory *td = &tif->tif_dir; + + tif->tif_postdecode = _TIFFNoPostDecode; + switch (td->td_photometric) + { + case PHOTOMETRIC_LOGLUV: + if (!LogLuvInitState(tif)) + break; + if (td->td_compression == COMPRESSION_SGILOG24) + { + tif->tif_decoderow = LogLuvDecode24; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv24toXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv24toLuv48; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = Luv24toRGB; + break; + } + } + else + { + tif->tif_decoderow = LogLuvDecode32; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv32toXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv32toLuv48; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = Luv32toRGB; + break; + } + } + return (1); + case PHOTOMETRIC_LOGL: + if (!LogL16InitState(tif)) + break; + tif->tif_decoderow = LogL16Decode; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = L16toY; + break; + case SGILOGDATAFMT_8BIT: + sp->tfunc = L16toGry; + break; + } + return (1); + default: + TIFFErrorExtR(tif, module, + "Inappropriate photometric interpretation %" PRIu16 + " for SGILog compression; %s", + td->td_photometric, "must be either LogLUV or LogL"); + break; + } + return (0); } -static int -LogLuvSetupEncode(TIFF* tif) +static int LogLuvSetupEncode(TIFF *tif) { - static const char module[] = "LogLuvSetupEncode"; - LogLuvState* sp = EncoderState(tif); - TIFFDirectory* td = &tif->tif_dir; - - switch (td->td_photometric) { - case PHOTOMETRIC_LOGLUV: - if (!LogLuvInitState(tif)) - return (0); - if (td->td_compression == COMPRESSION_SGILOG24) { - tif->tif_encoderow = LogLuvEncode24; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv24fromXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv24fromLuv48; - break; - case SGILOGDATAFMT_RAW: - break; - default: - goto notsupported; - } - } else { - tif->tif_encoderow = LogLuvEncode32; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = Luv32fromXYZ; - break; - case SGILOGDATAFMT_16BIT: - sp->tfunc = Luv32fromLuv48; - break; - case SGILOGDATAFMT_RAW: - break; - default: - goto notsupported; - } - } - break; - case PHOTOMETRIC_LOGL: - if (!LogL16InitState(tif)) - return (0); - tif->tif_encoderow = LogL16Encode; - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - sp->tfunc = L16fromY; - break; - case SGILOGDATAFMT_16BIT: - break; - default: - goto notsupported; - } - break; - default: - TIFFErrorExtR(tif, module, - "Inappropriate photometric interpretation %"PRIu16" for SGILog compression; %s", - td->td_photometric, "must be either LogLUV or LogL"); - return (0); - } - sp->encoder_state = 1; - return (1); + static const char module[] = "LogLuvSetupEncode"; + LogLuvState *sp = EncoderState(tif); + TIFFDirectory *td = &tif->tif_dir; + + switch (td->td_photometric) + { + case PHOTOMETRIC_LOGLUV: + if (!LogLuvInitState(tif)) + return (0); + if (td->td_compression == COMPRESSION_SGILOG24) + { + tif->tif_encoderow = LogLuvEncode24; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv24fromXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv24fromLuv48; + break; + case SGILOGDATAFMT_RAW: + break; + default: + goto notsupported; + } + } + else + { + tif->tif_encoderow = LogLuvEncode32; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = Luv32fromXYZ; + break; + case SGILOGDATAFMT_16BIT: + sp->tfunc = Luv32fromLuv48; + break; + case SGILOGDATAFMT_RAW: + break; + default: + goto notsupported; + } + } + break; + case PHOTOMETRIC_LOGL: + if (!LogL16InitState(tif)) + return (0); + tif->tif_encoderow = LogL16Encode; + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + sp->tfunc = L16fromY; + break; + case SGILOGDATAFMT_16BIT: + break; + default: + goto notsupported; + } + break; + default: + TIFFErrorExtR(tif, module, + "Inappropriate photometric interpretation %" PRIu16 + " for SGILog compression; %s", + td->td_photometric, "must be either LogLUV or LogL"); + return (0); + } + sp->encoder_state = 1; + return (1); notsupported: - TIFFErrorExtR(tif, module, - "SGILog compression supported only for %s, or raw data", - td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv"); - return (0); + TIFFErrorExtR(tif, module, + "SGILog compression supported only for %s, or raw data", + td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv"); + return (0); } -static void -LogLuvClose(TIFF* tif) +static void LogLuvClose(TIFF *tif) { - LogLuvState* sp = (LogLuvState*) tif->tif_data; - TIFFDirectory *td = &tif->tif_dir; - - assert(sp != 0); - /* - * For consistency, we always want to write out the same - * bitspersample and sampleformat for our TIFF file, - * regardless of the data format being used by the application. - * Since this routine is called after tags have been set but - * before they have been recorded in the file, we reset them here. - * Note: this is really a nasty approach. See PixarLogClose - */ - if( sp->encoder_state ) - { - /* See PixarLogClose. Might avoid issues with tags whose size depends - * on those below, but not completely sure this is enough. */ - td->td_samplesperpixel = - (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; - td->td_bitspersample = 16; - td->td_sampleformat = SAMPLEFORMAT_INT; - } + LogLuvState *sp = (LogLuvState *)tif->tif_data; + TIFFDirectory *td = &tif->tif_dir; + + assert(sp != 0); + /* + * For consistency, we always want to write out the same + * bitspersample and sampleformat for our TIFF file, + * regardless of the data format being used by the application. + * Since this routine is called after tags have been set but + * before they have been recorded in the file, we reset them here. + * Note: this is really a nasty approach. See PixarLogClose + */ + if (sp->encoder_state) + { + /* See PixarLogClose. Might avoid issues with tags whose size depends + * on those below, but not completely sure this is enough. */ + td->td_samplesperpixel = + (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3; + td->td_bitspersample = 16; + td->td_sampleformat = SAMPLEFORMAT_INT; + } } -static void -LogLuvCleanup(TIFF* tif) +static void LogLuvCleanup(TIFF *tif) { - LogLuvState* sp = (LogLuvState *)tif->tif_data; + LogLuvState *sp = (LogLuvState *)tif->tif_data; - assert(sp != 0); + assert(sp != 0); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; - if (sp->tbuf) - _TIFFfreeExt(tif, sp->tbuf); - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; + if (sp->tbuf) + _TIFFfreeExt(tif, sp->tbuf); + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } -static int -LogLuvVSetField(TIFF* tif, uint32_t tag, va_list ap) +static int LogLuvVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[] = "LogLuvVSetField"; - LogLuvState* sp = DecoderState(tif); - int bps, fmt; - - switch (tag) { - case TIFFTAG_SGILOGDATAFMT: - sp->user_datafmt = (int) va_arg(ap, int); - /* - * Tweak the TIFF header so that the rest of libtiff knows what - * size of data will be passed between app and library, and - * assume that the app knows what it is doing and is not - * confused by these header manipulations... - */ - switch (sp->user_datafmt) { - case SGILOGDATAFMT_FLOAT: - bps = 32; - fmt = SAMPLEFORMAT_IEEEFP; - break; - case SGILOGDATAFMT_16BIT: - bps = 16; - fmt = SAMPLEFORMAT_INT; - break; - case SGILOGDATAFMT_RAW: - bps = 32; - fmt = SAMPLEFORMAT_UINT; - TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); - break; - case SGILOGDATAFMT_8BIT: - bps = 8; - fmt = SAMPLEFORMAT_UINT; - break; - default: - TIFFErrorExtR(tif, tif->tif_name, - "Unknown data format %d for LogLuv compression", - sp->user_datafmt); - return (0); - } - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt); - /* - * Must recalculate sizes should bits/sample change. - */ - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t) -1; - tif->tif_scanlinesize = TIFFScanlineSize(tif); - return (1); - case TIFFTAG_SGILOGENCODE: - sp->encode_meth = (int) va_arg(ap, int); - if (sp->encode_meth != SGILOGENCODE_NODITHER && - sp->encode_meth != SGILOGENCODE_RANDITHER) { - TIFFErrorExtR(tif, module, - "Unknown encoding %d for LogLuv compression", - sp->encode_meth); - return (0); - } - return (1); - default: - return (*sp->vsetparent)(tif, tag, ap); - } + static const char module[] = "LogLuvVSetField"; + LogLuvState *sp = DecoderState(tif); + int bps, fmt; + + switch (tag) + { + case TIFFTAG_SGILOGDATAFMT: + sp->user_datafmt = (int)va_arg(ap, int); + /* + * Tweak the TIFF header so that the rest of libtiff knows what + * size of data will be passed between app and library, and + * assume that the app knows what it is doing and is not + * confused by these header manipulations... + */ + switch (sp->user_datafmt) + { + case SGILOGDATAFMT_FLOAT: + bps = 32; + fmt = SAMPLEFORMAT_IEEEFP; + break; + case SGILOGDATAFMT_16BIT: + bps = 16; + fmt = SAMPLEFORMAT_INT; + break; + case SGILOGDATAFMT_RAW: + bps = 32; + fmt = SAMPLEFORMAT_UINT; + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); + break; + case SGILOGDATAFMT_8BIT: + bps = 8; + fmt = SAMPLEFORMAT_UINT; + break; + default: + TIFFErrorExtR( + tif, tif->tif_name, + "Unknown data format %d for LogLuv compression", + sp->user_datafmt); + return (0); + } + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt); + /* + * Must recalculate sizes should bits/sample change. + */ + tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)-1; + tif->tif_scanlinesize = TIFFScanlineSize(tif); + return (1); + case TIFFTAG_SGILOGENCODE: + sp->encode_meth = (int)va_arg(ap, int); + if (sp->encode_meth != SGILOGENCODE_NODITHER && + sp->encode_meth != SGILOGENCODE_RANDITHER) + { + TIFFErrorExtR(tif, module, + "Unknown encoding %d for LogLuv compression", + sp->encode_meth); + return (0); + } + return (1); + default: + return (*sp->vsetparent)(tif, tag, ap); + } } -static int -LogLuvVGetField(TIFF* tif, uint32_t tag, va_list ap) +static int LogLuvVGetField(TIFF *tif, uint32_t tag, va_list ap) { - LogLuvState *sp = (LogLuvState *)tif->tif_data; - - switch (tag) { - case TIFFTAG_SGILOGDATAFMT: - *va_arg(ap, int*) = sp->user_datafmt; - return (1); - default: - return (*sp->vgetparent)(tif, tag, ap); - } + LogLuvState *sp = (LogLuvState *)tif->tif_data; + + switch (tag) + { + case TIFFTAG_SGILOGDATAFMT: + *va_arg(ap, int *) = sp->user_datafmt; + return (1); + default: + return (*sp->vgetparent)(tif, tag, ap); + } } static const TIFFField LogLuvFields[] = { - { TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL}, - { TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL} -}; + {TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL}, + {TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL}}; -int -TIFFInitSGILog(TIFF* tif, int scheme) +int TIFFInitSGILog(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitSGILog"; - LogLuvState* sp; - - assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, LogLuvFields, - TIFFArrayCount(LogLuvFields))) { - TIFFErrorExtR(tif, module, - "Merging SGILog codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t*) _TIFFmallocExt(tif, sizeof (LogLuvState)); - if (tif->tif_data == NULL) - goto bad; - sp = (LogLuvState*) tif->tif_data; - _TIFFmemset((void*)sp, 0, sizeof (*sp)); - sp->user_datafmt = SGILOGDATAFMT_UNKNOWN; - sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ? - SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER; - sp->tfunc = _logLuvNop; - - /* - * Install codec methods. - * NB: tif_decoderow & tif_encoderow are filled - * in at setup time. - */ - tif->tif_fixuptags = LogLuvFixupTags; - tif->tif_setupdecode = LogLuvSetupDecode; - tif->tif_decodestrip = LogLuvDecodeStrip; - tif->tif_decodetile = LogLuvDecodeTile; - tif->tif_setupencode = LogLuvSetupEncode; - tif->tif_encodestrip = LogLuvEncodeStrip; - tif->tif_encodetile = LogLuvEncodeTile; - tif->tif_close = LogLuvClose; - tif->tif_cleanup = LogLuvCleanup; - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = LogLuvVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = LogLuvVSetField; /* hook for codec tags */ - - return (1); + static const char module[] = "TIFFInitSGILog"; + LogLuvState *sp; + + assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, LogLuvFields, TIFFArrayCount(LogLuvFields))) + { + TIFFErrorExtR(tif, module, "Merging SGILog codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LogLuvState)); + if (tif->tif_data == NULL) + goto bad; + sp = (LogLuvState *)tif->tif_data; + _TIFFmemset((void *)sp, 0, sizeof(*sp)); + sp->user_datafmt = SGILOGDATAFMT_UNKNOWN; + sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ? SGILOGENCODE_RANDITHER + : SGILOGENCODE_NODITHER; + sp->tfunc = _logLuvNop; + + /* + * Install codec methods. + * NB: tif_decoderow & tif_encoderow are filled + * in at setup time. + */ + tif->tif_fixuptags = LogLuvFixupTags; + tif->tif_setupdecode = LogLuvSetupDecode; + tif->tif_decodestrip = LogLuvDecodeStrip; + tif->tif_decodetile = LogLuvDecodeTile; + tif->tif_setupencode = LogLuvSetupEncode; + tif->tif_encodestrip = LogLuvEncodeStrip; + tif->tif_encodetile = LogLuvEncodeTile; + tif->tif_close = LogLuvClose; + tif->tif_cleanup = LogLuvCleanup; + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = LogLuvVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = LogLuvVSetField; /* hook for codec tags */ + + return (1); bad: - TIFFErrorExtR(tif, module, - "%s: No space for LogLuv state block", tif->tif_name); - return (0); + TIFFErrorExtR(tif, module, "%s: No space for LogLuv state block", + tif->tif_name); + return (0); } #endif /* LOGLUV_SUPPORT */ diff --git a/libtiff/tif_lzma.c b/libtiff/tif_lzma.c index 1f5b3615..4cfd5e88 100644 --- a/libtiff/tif_lzma.c +++ b/libtiff/tif_lzma.c @@ -33,469 +33,488 @@ * The codec is derived from ZLIB codec (tif_zip.c). */ -#include "tif_predict.h" #include "lzma.h" +#include "tif_predict.h" #include <stdio.h> /* * State block for each open TIFF file using LZMA2 compression/decompression. */ -typedef struct { - TIFFPredictorState predict; - lzma_stream stream; - lzma_filter filters[LZMA_FILTERS_MAX + 1]; - lzma_options_delta opt_delta; /* delta filter options */ - lzma_options_lzma opt_lzma; /* LZMA2 filter options */ - int preset; /* compression level */ - lzma_check check; /* type of the integrity check */ - int state; /* state flags */ +typedef struct +{ + TIFFPredictorState predict; + lzma_stream stream; + lzma_filter filters[LZMA_FILTERS_MAX + 1]; + lzma_options_delta opt_delta; /* delta filter options */ + lzma_options_lzma opt_lzma; /* LZMA2 filter options */ + int preset; /* compression level */ + lzma_check check; /* type of the integrity check */ + int state; /* state flags */ #define LSTATE_INIT_DECODE 0x01 #define LSTATE_INIT_ENCODE 0x02 - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ } LZMAState; -#define LState(tif) ((LZMAState*) (tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) +#define LState(tif) ((LZMAState *)(tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) -static int LZMAEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s); -static int LZMADecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s); +static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -static const char * -LZMAStrerror(lzma_ret ret) +static const char *LZMAStrerror(lzma_ret ret) { - switch (ret) { - case LZMA_OK: - return "operation completed successfully"; - case LZMA_STREAM_END: - return "end of stream was reached"; - case LZMA_NO_CHECK: - return "input stream has no integrity check"; - case LZMA_UNSUPPORTED_CHECK: - return "cannot calculate the integrity check"; - case LZMA_GET_CHECK: - return "integrity check type is now available"; - case LZMA_MEM_ERROR: - return "cannot allocate memory"; - case LZMA_MEMLIMIT_ERROR: - return "memory usage limit was reached"; - case LZMA_FORMAT_ERROR: - return "file format not recognized"; - case LZMA_OPTIONS_ERROR: - return "invalid or unsupported options"; - case LZMA_DATA_ERROR: - return "data is corrupt"; - case LZMA_BUF_ERROR: - return "no progress is possible (stream is truncated or corrupt)"; - case LZMA_PROG_ERROR: - return "programming error"; - default: - return "unidentified liblzma error"; - } + switch (ret) + { + case LZMA_OK: + return "operation completed successfully"; + case LZMA_STREAM_END: + return "end of stream was reached"; + case LZMA_NO_CHECK: + return "input stream has no integrity check"; + case LZMA_UNSUPPORTED_CHECK: + return "cannot calculate the integrity check"; + case LZMA_GET_CHECK: + return "integrity check type is now available"; + case LZMA_MEM_ERROR: + return "cannot allocate memory"; + case LZMA_MEMLIMIT_ERROR: + return "memory usage limit was reached"; + case LZMA_FORMAT_ERROR: + return "file format not recognized"; + case LZMA_OPTIONS_ERROR: + return "invalid or unsupported options"; + case LZMA_DATA_ERROR: + return "data is corrupt"; + case LZMA_BUF_ERROR: + return "no progress is possible (stream is truncated or corrupt)"; + case LZMA_PROG_ERROR: + return "programming error"; + default: + return "unidentified liblzma error"; + } } -static int -LZMAFixupTags(TIFF* tif) +static int LZMAFixupTags(TIFF *tif) { - (void) tif; - return 1; + (void)tif; + return 1; } -static int -LZMASetupDecode(TIFF* tif) +static int LZMASetupDecode(TIFF *tif) { - LZMAState* sp = DecoderState(tif); - - assert(sp != NULL); - - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) { - lzma_end(&sp->stream); - sp->state = 0; - } - - sp->state |= LSTATE_INIT_DECODE; - return 1; + LZMAState *sp = DecoderState(tif); + + assert(sp != NULL); + + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) + { + lzma_end(&sp->stream); + sp->state = 0; + } + + sp->state |= LSTATE_INIT_DECODE; + return 1; } /* * Setup state for decoding a strip. */ -static int -LZMAPreDecode(TIFF* tif, uint16_t s) +static int LZMAPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "LZMAPreDecode"; - LZMAState* sp = DecoderState(tif); - lzma_ret ret; - - (void) s; - assert(sp != NULL); - - if( (sp->state & LSTATE_INIT_DECODE) == 0 ) - tif->tif_setupdecode(tif); - - sp->stream.next_in = tif->tif_rawdata; - sp->stream.avail_in = (size_t) tif->tif_rawcc; - if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) { - TIFFErrorExtR(tif, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } - - /* - * Disable memory limit when decoding. UINT64_MAX is a flag to disable - * the limit, we are passing (uint64_t)-1 which should be the same. - */ - ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0); - if (ret != LZMA_OK) { - TIFFErrorExtR(tif, module, - "Error initializing the stream decoder, %s", - LZMAStrerror(ret)); - return 0; - } - return 1; + static const char module[] = "LZMAPreDecode"; + LZMAState *sp = DecoderState(tif); + lzma_ret ret; + + (void)s; + assert(sp != NULL); + + if ((sp->state & LSTATE_INIT_DECODE) == 0) + tif->tif_setupdecode(tif); + + sp->stream.next_in = tif->tif_rawdata; + sp->stream.avail_in = (size_t)tif->tif_rawcc; + if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) + { + TIFFErrorExtR(tif, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + + /* + * Disable memory limit when decoding. UINT64_MAX is a flag to disable + * the limit, we are passing (uint64_t)-1 which should be the same. + */ + ret = lzma_stream_decoder(&sp->stream, (uint64_t)-1, 0); + if (ret != LZMA_OK) + { + TIFFErrorExtR(tif, module, "Error initializing the stream decoder, %s", + LZMAStrerror(ret)); + return 0; + } + return 1; } -static int -LZMADecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) +static int LZMADecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "LZMADecode"; - LZMAState* sp = DecoderState(tif); - - (void) s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); - - sp->stream.next_in = tif->tif_rawcp; - sp->stream.avail_in = (size_t) tif->tif_rawcc; - - sp->stream.next_out = op; - sp->stream.avail_out = (size_t) occ; - if ((tmsize_t)sp->stream.avail_out != occ) { - TIFFErrorExtR(tif, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } - - do { - /* - * Save the current stream state to properly recover from the - * decoding errors later. - */ - const uint8_t *next_in = sp->stream.next_in; - size_t avail_in = sp->stream.avail_in; - - lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); - if (ret == LZMA_STREAM_END) - break; - if (ret == LZMA_MEMLIMIT_ERROR) { - lzma_ret r = lzma_stream_decoder(&sp->stream, - lzma_memusage(&sp->stream), 0); - if (r != LZMA_OK) { - TIFFErrorExtR(tif, module, - "Error initializing the stream decoder, %s", - LZMAStrerror(r)); - break; - } - sp->stream.next_in = next_in; - sp->stream.avail_in = avail_in; - continue; - } - if (ret != LZMA_OK) { - TIFFErrorExtR(tif, module, - "Decoding error at scanline %"PRIu32", %s", - tif->tif_row, LZMAStrerror(ret)); - break; - } - } while (sp->stream.avail_out > 0); - if (sp->stream.avail_out != 0) { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %"PRIu32" (short %"TIFF_SIZE_FORMAT" bytes)", - tif->tif_row, sp->stream.avail_out); - return 0; - } - - tif->tif_rawcp = (uint8_t *)sp->stream.next_in; /* cast away const */ - tif->tif_rawcc = sp->stream.avail_in; - - return 1; + static const char module[] = "LZMADecode"; + LZMAState *sp = DecoderState(tif); + + (void)s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); + + sp->stream.next_in = tif->tif_rawcp; + sp->stream.avail_in = (size_t)tif->tif_rawcc; + + sp->stream.next_out = op; + sp->stream.avail_out = (size_t)occ; + if ((tmsize_t)sp->stream.avail_out != occ) + { + TIFFErrorExtR(tif, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + + do + { + /* + * Save the current stream state to properly recover from the + * decoding errors later. + */ + const uint8_t *next_in = sp->stream.next_in; + size_t avail_in = sp->stream.avail_in; + + lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); + if (ret == LZMA_STREAM_END) + break; + if (ret == LZMA_MEMLIMIT_ERROR) + { + lzma_ret r = + lzma_stream_decoder(&sp->stream, lzma_memusage(&sp->stream), 0); + if (r != LZMA_OK) + { + TIFFErrorExtR(tif, module, + "Error initializing the stream decoder, %s", + LZMAStrerror(r)); + break; + } + sp->stream.next_in = next_in; + sp->stream.avail_in = avail_in; + continue; + } + if (ret != LZMA_OK) + { + TIFFErrorExtR(tif, module, + "Decoding error at scanline %" PRIu32 ", %s", + tif->tif_row, LZMAStrerror(ret)); + break; + } + } while (sp->stream.avail_out > 0); + if (sp->stream.avail_out != 0) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %" PRIu32 + " (short %" TIFF_SIZE_FORMAT " bytes)", + tif->tif_row, sp->stream.avail_out); + return 0; + } + + tif->tif_rawcp = (uint8_t *)sp->stream.next_in; /* cast away const */ + tif->tif_rawcc = sp->stream.avail_in; + + return 1; } -static int -LZMASetupEncode(TIFF* tif) +static int LZMASetupEncode(TIFF *tif) { - LZMAState* sp = EncoderState(tif); + LZMAState *sp = EncoderState(tif); - assert(sp != NULL); - if (sp->state & LSTATE_INIT_DECODE) { - lzma_end(&sp->stream); - sp->state = 0; - } + assert(sp != NULL); + if (sp->state & LSTATE_INIT_DECODE) + { + lzma_end(&sp->stream); + sp->state = 0; + } - sp->state |= LSTATE_INIT_ENCODE; - return 1; + sp->state |= LSTATE_INIT_ENCODE; + return 1; } /* * Reset encoding state at the start of a strip. */ -static int -LZMAPreEncode(TIFF* tif, uint16_t s) +static int LZMAPreEncode(TIFF *tif, uint16_t s) { - static const char module[] = "LZMAPreEncode"; - LZMAState *sp = EncoderState(tif); - lzma_ret ret; - - (void) s; - assert(sp != NULL); - if( sp->state != LSTATE_INIT_ENCODE ) - tif->tif_setupencode(tif); - - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (size_t)tif->tif_rawdatasize; - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { - TIFFErrorExtR(tif, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } - ret = lzma_stream_encoder(&sp->stream, sp->filters, sp->check); - if (ret != LZMA_OK) { - TIFFErrorExtR(tif, module, - "Error in lzma_stream_encoder(): %s", LZMAStrerror(ret)); - return 0; - } - return 1; + static const char module[] = "LZMAPreEncode"; + LZMAState *sp = EncoderState(tif); + lzma_ret ret; + + (void)s; + assert(sp != NULL); + if (sp->state != LSTATE_INIT_ENCODE) + tif->tif_setupencode(tif); + + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (size_t)tif->tif_rawdatasize; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + TIFFErrorExtR(tif, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + ret = lzma_stream_encoder(&sp->stream, sp->filters, sp->check); + if (ret != LZMA_OK) + { + TIFFErrorExtR(tif, module, "Error in lzma_stream_encoder(): %s", + LZMAStrerror(ret)); + return 0; + } + return 1; } /* * Encode a chunk of pixels. */ -static int -LZMAEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int LZMAEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "LZMAEncode"; - LZMAState *sp = EncoderState(tif); - - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); - - (void) s; - sp->stream.next_in = bp; - sp->stream.avail_in = (size_t) cc; - if ((tmsize_t)sp->stream.avail_in != cc) { - TIFFErrorExtR(tif, module, - "Liblzma cannot deal with buffers this size"); - return 0; - } - do { - lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); - if (ret != LZMA_OK) { - TIFFErrorExtR(tif, module, - "Encoding error at scanline %"PRIu32", %s", - tif->tif_row, LZMAStrerror(ret)); - return 0; - } - if (sp->stream.avail_out == 0) { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in LZMAPreEncode */ - } - } while (sp->stream.avail_in > 0); - return 1; + static const char module[] = "LZMAEncode"; + LZMAState *sp = EncoderState(tif); + + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); + + (void)s; + sp->stream.next_in = bp; + sp->stream.avail_in = (size_t)cc; + if ((tmsize_t)sp->stream.avail_in != cc) + { + TIFFErrorExtR(tif, module, + "Liblzma cannot deal with buffers this size"); + return 0; + } + do + { + lzma_ret ret = lzma_code(&sp->stream, LZMA_RUN); + if (ret != LZMA_OK) + { + TIFFErrorExtR(tif, module, + "Encoding error at scanline %" PRIu32 ", %s", + tif->tif_row, LZMAStrerror(ret)); + return 0; + } + if (sp->stream.avail_out == 0) + { + tif->tif_rawcc = tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = + (size_t) + tif->tif_rawdatasize; /* this is a safe typecast, as check + is made already in LZMAPreEncode */ + } + } while (sp->stream.avail_in > 0); + return 1; } /* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ -static int -LZMAPostEncode(TIFF* tif) +static int LZMAPostEncode(TIFF *tif) { - static const char module[] = "LZMAPostEncode"; - LZMAState *sp = EncoderState(tif); - lzma_ret ret; - - sp->stream.avail_in = 0; - do { - ret = lzma_code(&sp->stream, LZMA_FINISH); - switch (ret) { - case LZMA_STREAM_END: - case LZMA_OK: - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { - tif->tif_rawcc = - tif->tif_rawdatasize - sp->stream.avail_out; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (size_t)tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */ - } - break; - default: - TIFFErrorExtR(tif, module, "Liblzma error: %s", - LZMAStrerror(ret)); - return 0; - } - } while (ret != LZMA_STREAM_END); - return 1; + static const char module[] = "LZMAPostEncode"; + LZMAState *sp = EncoderState(tif); + lzma_ret ret; + + sp->stream.avail_in = 0; + do + { + ret = lzma_code(&sp->stream, LZMA_FINISH); + switch (ret) + { + case LZMA_STREAM_END: + case LZMA_OK: + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = + (size_t) + tif->tif_rawdatasize; /* this is a safe typecast, as + check is made already in + ZIPPreEncode */ + } + break; + default: + TIFFErrorExtR(tif, module, "Liblzma error: %s", + LZMAStrerror(ret)); + return 0; + } + } while (ret != LZMA_STREAM_END); + return 1; } -static void -LZMACleanup(TIFF* tif) +static void LZMACleanup(TIFF *tif) { - LZMAState* sp = LState(tif); + LZMAState *sp = LState(tif); - assert(sp != 0); + assert(sp != 0); - (void)TIFFPredictorCleanup(tif); + (void)TIFFPredictorCleanup(tif); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; - if (sp->state) { - lzma_end(&sp->stream); - sp->state = 0; - } - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; + if (sp->state) + { + lzma_end(&sp->stream); + sp->state = 0; + } + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } -static int -LZMAVSetField(TIFF* tif, uint32_t tag, va_list ap) +static int LZMAVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[] = "LZMAVSetField"; - LZMAState* sp = LState(tif); - - switch (tag) { - case TIFFTAG_LZMAPRESET: - sp->preset = (int) va_arg(ap, int); - lzma_lzma_preset(&sp->opt_lzma, sp->preset); - if (sp->state & LSTATE_INIT_ENCODE) { - lzma_ret ret = lzma_stream_encoder(&sp->stream, - sp->filters, - sp->check); - if (ret != LZMA_OK) { - TIFFErrorExtR(tif, module, - "Liblzma error: %s", - LZMAStrerror(ret)); - } - } - return 1; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ + static const char module[] = "LZMAVSetField"; + LZMAState *sp = LState(tif); + + switch (tag) + { + case TIFFTAG_LZMAPRESET: + sp->preset = (int)va_arg(ap, int); + lzma_lzma_preset(&sp->opt_lzma, sp->preset); + if (sp->state & LSTATE_INIT_ENCODE) + { + lzma_ret ret = + lzma_stream_encoder(&sp->stream, sp->filters, sp->check); + if (ret != LZMA_OK) + { + TIFFErrorExtR(tif, module, "Liblzma error: %s", + LZMAStrerror(ret)); + } + } + return 1; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ } -static int -LZMAVGetField(TIFF* tif, uint32_t tag, va_list ap) +static int LZMAVGetField(TIFF *tif, uint32_t tag, va_list ap) { - LZMAState* sp = LState(tif); - - switch (tag) { - case TIFFTAG_LZMAPRESET: - *va_arg(ap, int*) = sp->preset; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; + LZMAState *sp = LState(tif); + + switch (tag) + { + case TIFFTAG_LZMAPRESET: + *va_arg(ap, int *) = sp->preset; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; } static const TIFFField lzmaFields[] = { - { TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, TRUE, FALSE, "LZMA2 Compression Preset", NULL }, + {TIFFTAG_LZMAPRESET, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, + "LZMA2 Compression Preset", NULL}, }; -int -TIFFInitLZMA(TIFF* tif, int scheme) +int TIFFInitLZMA(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitLZMA"; - LZMAState* sp; - lzma_stream tmp_stream = LZMA_STREAM_INIT; - - (void)scheme; - assert( scheme == COMPRESSION_LZMA ); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) { - TIFFErrorExtR(tif, module, - "Merging LZMA2 codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t*) _TIFFmallocExt(tif, sizeof(LZMAState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); - memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream)); - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */ - sp->check = LZMA_CHECK_NONE; - sp->state = 0; - - /* Data filters. So far we are using delta and LZMA2 filters only. */ - sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE; - /* - * The sample size in bytes seems to be reasonable distance for delta - * filter. - */ - sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) ? - 1 : tif->tif_dir.td_bitspersample / 8; - sp->filters[0].id = LZMA_FILTER_DELTA; - sp->filters[0].options = &sp->opt_delta; - - lzma_lzma_preset(&sp->opt_lzma, sp->preset); - sp->filters[1].id = LZMA_FILTER_LZMA2; - sp->filters[1].options = &sp->opt_lzma; - - sp->filters[2].id = LZMA_VLI_UNKNOWN; - sp->filters[2].options = NULL; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = LZMAFixupTags; - tif->tif_setupdecode = LZMASetupDecode; - tif->tif_predecode = LZMAPreDecode; - tif->tif_decoderow = LZMADecode; - tif->tif_decodestrip = LZMADecode; - tif->tif_decodetile = LZMADecode; - tif->tif_setupencode = LZMASetupEncode; - tif->tif_preencode = LZMAPreEncode; - tif->tif_postencode = LZMAPostEncode; - tif->tif_encoderow = LZMAEncode; - tif->tif_encodestrip = LZMAEncode; - tif->tif_encodetile = LZMAEncode; - tif->tif_cleanup = LZMACleanup; - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); - return 1; + static const char module[] = "TIFFInitLZMA"; + LZMAState *sp; + lzma_stream tmp_stream = LZMA_STREAM_INIT; + + (void)scheme; + assert(scheme == COMPRESSION_LZMA); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, lzmaFields, TIFFArrayCount(lzmaFields))) + { + TIFFErrorExtR(tif, module, "Merging LZMA2 codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZMAState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + memcpy(&sp->stream, &tmp_stream, sizeof(lzma_stream)); + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = LZMAVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = LZMAVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->preset = LZMA_PRESET_DEFAULT; /* default comp. level */ + sp->check = LZMA_CHECK_NONE; + sp->state = 0; + + /* Data filters. So far we are using delta and LZMA2 filters only. */ + sp->opt_delta.type = LZMA_DELTA_TYPE_BYTE; + /* + * The sample size in bytes seems to be reasonable distance for delta + * filter. + */ + sp->opt_delta.dist = (tif->tif_dir.td_bitspersample % 8) + ? 1 + : tif->tif_dir.td_bitspersample / 8; + sp->filters[0].id = LZMA_FILTER_DELTA; + sp->filters[0].options = &sp->opt_delta; + + lzma_lzma_preset(&sp->opt_lzma, sp->preset); + sp->filters[1].id = LZMA_FILTER_LZMA2; + sp->filters[1].options = &sp->opt_lzma; + + sp->filters[2].id = LZMA_VLI_UNKNOWN; + sp->filters[2].options = NULL; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = LZMAFixupTags; + tif->tif_setupdecode = LZMASetupDecode; + tif->tif_predecode = LZMAPreDecode; + tif->tif_decoderow = LZMADecode; + tif->tif_decodestrip = LZMADecode; + tif->tif_decodetile = LZMADecode; + tif->tif_setupencode = LZMASetupEncode; + tif->tif_preencode = LZMAPreEncode; + tif->tif_postencode = LZMAPostEncode; + tif->tif_encoderow = LZMAEncode; + tif->tif_encodestrip = LZMAEncode; + tif->tif_encodetile = LZMAEncode; + tif->tif_cleanup = LZMACleanup; + /* + * Setup predictor setup. + */ + (void)TIFFPredictorInit(tif); + return 1; bad: - TIFFErrorExtR(tif, module, - "No space for LZMA2 state block"); - return 0; + TIFFErrorExtR(tif, module, "No space for LZMA2 state block"); + return 0; } #endif /* LZMA_SUPPORT */ diff --git a/libtiff/tif_lzw.c b/libtiff/tif_lzw.c index a313a651..ba75a07e 100644 --- a/libtiff/tif_lzw.c +++ b/libtiff/tif_lzw.c @@ -58,27 +58,27 @@ typedef size_t WordType; * * Future revisions to the TIFF spec are expected to "clarify this issue". */ -#define LZW_COMPAT /* include backwards compatibility code */ +#define LZW_COMPAT /* include backwards compatibility code */ -#define MAXCODE(n) ((1L<<(n))-1) +#define MAXCODE(n) ((1L << (n)) - 1) /* * The TIFF spec specifies that encoded bit * strings range from 9 to 12 bits. */ -#define BITS_MIN 9 /* start with 9 bits */ -#define BITS_MAX 12 /* max of 12 bit strings */ +#define BITS_MIN 9 /* start with 9 bits */ +#define BITS_MAX 12 /* max of 12 bit strings */ /* predefined codes */ -#define CODE_CLEAR 256 /* code to clear string table */ -#define CODE_EOI 257 /* end-of-information code */ -#define CODE_FIRST 258 /* first free code entry */ -#define CODE_MAX MAXCODE(BITS_MAX) -#define HSIZE 9001L /* 91% occupancy */ -#define HSHIFT (13-8) +#define CODE_CLEAR 256 /* code to clear string table */ +#define CODE_EOI 257 /* end-of-information code */ +#define CODE_FIRST 258 /* first free code entry */ +#define CODE_MAX MAXCODE(BITS_MAX) +#define HSIZE 9001L /* 91% occupancy */ +#define HSHIFT (13 - 8) #ifdef LZW_COMPAT /* NB: +1024 is for compatibility with old files */ -#define CSIZE (MAXCODE(BITS_MAX)+1024L) +#define CSIZE (MAXCODE(BITS_MAX) + 1024L) #else -#define CSIZE (MAXCODE(BITS_MAX)+1L) +#define CSIZE (MAXCODE(BITS_MAX) + 1L) #endif /* @@ -86,231 +86,239 @@ typedef size_t WordType; * compression/decompression. Note that the predictor * state block must be first in this data structure. */ -typedef struct { - TIFFPredictorState predict; /* predictor super class */ +typedef struct +{ + TIFFPredictorState predict; /* predictor super class */ - unsigned short nbits; /* # of bits/code */ - unsigned short maxcode; /* maximum code for lzw_nbits */ - unsigned short free_ent; /* next free entry in hash table */ - WordType nextdata; /* next bits of i/o */ - long nextbits; /* # of valid bits in lzw_nextdata */ + unsigned short nbits; /* # of bits/code */ + unsigned short maxcode; /* maximum code for lzw_nbits */ + unsigned short free_ent; /* next free entry in hash table */ + WordType nextdata; /* next bits of i/o */ + long nextbits; /* # of valid bits in lzw_nextdata */ - int rw_mode; /* preserve rw_mode from init */ + int rw_mode; /* preserve rw_mode from init */ } LZWBaseState; -#define lzw_nbits base.nbits -#define lzw_maxcode base.maxcode -#define lzw_free_ent base.free_ent -#define lzw_nextdata base.nextdata -#define lzw_nextbits base.nextbits +#define lzw_nbits base.nbits +#define lzw_maxcode base.maxcode +#define lzw_free_ent base.free_ent +#define lzw_nextdata base.nextdata +#define lzw_nextbits base.nextbits /* * Encoding-specific state. */ -typedef uint16_t hcode_t; /* codes fit in 16 bits */ -typedef struct { - long hash; - hcode_t code; +typedef uint16_t hcode_t; /* codes fit in 16 bits */ +typedef struct +{ + long hash; + hcode_t code; } hash_t; /* * Decoding-specific state. */ -typedef struct code_ent { - struct code_ent *next; - unsigned short length; /* string len, including this token */ - /* firstchar should be placed immediately before value in this structure */ - unsigned char firstchar; /* first token of string */ - unsigned char value; /* data value */ - bool repeated; +typedef struct code_ent +{ + struct code_ent *next; + unsigned short length; /* string len, including this token */ + /* firstchar should be placed immediately before value in this structure */ + unsigned char firstchar; /* first token of string */ + unsigned char value; /* data value */ + bool repeated; } code_t; -typedef int (*decodeFunc)(TIFF*, uint8_t*, tmsize_t, uint16_t); - -typedef struct { - LZWBaseState base; - - /* Decoding specific data */ - long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ - tmsize_t dec_restart; /* restart count */ - uint64_t dec_bitsleft; /* available bits in raw data */ - tmsize_t old_tif_rawcc; /* value of tif_rawcc at the end of the previous TIFLZWDecode() call */ - decodeFunc dec_decode; /* regular or backwards compatible */ - code_t* dec_codep; /* current recognized code */ - code_t* dec_oldcodep; /* previously recognized code */ - code_t* dec_free_entp; /* next free entry */ - code_t* dec_maxcodep; /* max available entry */ - code_t* dec_codetab; /* kept separate for small machines */ - int read_error; /* whether a read error has occurred, and which should cause further reads in the same strip/tile to be aborted */ - - /* Encoding specific data */ - int enc_oldcode; /* last code encountered */ - tmsize_t enc_checkpoint; /* point at which to clear table */ -#define CHECK_GAP 10000 /* enc_ratio check interval */ - tmsize_t enc_ratio; /* current compression ratio */ - tmsize_t enc_incount; /* (input) data bytes encoded */ - tmsize_t enc_outcount; /* encoded (output) bytes */ - uint8_t* enc_rawlimit; /* bound on tif_rawdata buffer */ - hash_t* enc_hashtab; /* kept separate for small machines */ +typedef int (*decodeFunc)(TIFF *, uint8_t *, tmsize_t, uint16_t); + +typedef struct +{ + LZWBaseState base; + + /* Decoding specific data */ + long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */ + tmsize_t dec_restart; /* restart count */ + uint64_t dec_bitsleft; /* available bits in raw data */ + tmsize_t old_tif_rawcc; /* value of tif_rawcc at the end of the previous + TIFLZWDecode() call */ + decodeFunc dec_decode; /* regular or backwards compatible */ + code_t *dec_codep; /* current recognized code */ + code_t *dec_oldcodep; /* previously recognized code */ + code_t *dec_free_entp; /* next free entry */ + code_t *dec_maxcodep; /* max available entry */ + code_t *dec_codetab; /* kept separate for small machines */ + int read_error; /* whether a read error has occurred, and which should cause + further reads in the same strip/tile to be aborted */ + + /* Encoding specific data */ + int enc_oldcode; /* last code encountered */ + tmsize_t enc_checkpoint; /* point at which to clear table */ +#define CHECK_GAP 10000 /* enc_ratio check interval */ + tmsize_t enc_ratio; /* current compression ratio */ + tmsize_t enc_incount; /* (input) data bytes encoded */ + tmsize_t enc_outcount; /* encoded (output) bytes */ + uint8_t *enc_rawlimit; /* bound on tif_rawdata buffer */ + hash_t *enc_hashtab; /* kept separate for small machines */ } LZWCodecState; -#define LZWState(tif) ((LZWBaseState*) (tif)->tif_data) -#define DecoderState(tif) ((LZWCodecState*) LZWState(tif)) -#define EncoderState(tif) ((LZWCodecState*) LZWState(tif)) +#define LZWState(tif) ((LZWBaseState *)(tif)->tif_data) +#define DecoderState(tif) ((LZWCodecState *)LZWState(tif)) +#define EncoderState(tif) ((LZWCodecState *)LZWState(tif)) -static int LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s); +static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s); #ifdef LZW_COMPAT -static int LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s); +static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s); #endif -static void cl_hash(LZWCodecState*); +static void cl_hash(LZWCodecState *); /* * LZW Decoder. */ -static int -LZWFixupTags(TIFF* tif) +static int LZWFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } -static int -LZWSetupDecode(TIFF* tif) +static int LZWSetupDecode(TIFF *tif) { - static const char module[] = "LZWSetupDecode"; - LZWCodecState* sp = DecoderState(tif); - int code; - - if( sp == NULL ) - { - /* - * Allocate state block so tag methods have storage to record - * values. - */ - tif->tif_data = (uint8_t*) _TIFFmallocExt(tif, sizeof(LZWCodecState)); - if (tif->tif_data == NULL) - { - TIFFErrorExtR(tif, module, "No space for LZW state block"); - return (0); - } - - sp = DecoderState(tif); - sp->dec_codetab = NULL; - sp->dec_decode = NULL; - - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); - } - - if (sp->dec_codetab == NULL) { - sp->dec_codetab = (code_t*)_TIFFmallocExt(tif, CSIZE*sizeof (code_t)); - if (sp->dec_codetab == NULL) { - TIFFErrorExtR(tif, module, - "No space for LZW code table"); - return (0); - } - /* - * Pre-load the table. - */ - code = 255; - do { - sp->dec_codetab[code].firstchar = (unsigned char)code; - sp->dec_codetab[code].value = (unsigned char)code; - sp->dec_codetab[code].repeated = true; - sp->dec_codetab[code].length = 1; - sp->dec_codetab[code].next = NULL; - } while (code--); - /* - * Zero-out the unused entries */ - /* Silence false positive */ - /* coverity[overrun-buffer-arg] */ - memset(&sp->dec_codetab[CODE_CLEAR], 0, - (CODE_FIRST - CODE_CLEAR) * sizeof (code_t)); - } - return (1); + static const char module[] = "LZWSetupDecode"; + LZWCodecState *sp = DecoderState(tif); + int code; + + if (sp == NULL) + { + /* + * Allocate state block so tag methods have storage to record + * values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZWCodecState)); + if (tif->tif_data == NULL) + { + TIFFErrorExtR(tif, module, "No space for LZW state block"); + return (0); + } + + sp = DecoderState(tif); + sp->dec_codetab = NULL; + sp->dec_decode = NULL; + + /* + * Setup predictor setup. + */ + (void)TIFFPredictorInit(tif); + } + + if (sp->dec_codetab == NULL) + { + sp->dec_codetab = (code_t *)_TIFFmallocExt(tif, CSIZE * sizeof(code_t)); + if (sp->dec_codetab == NULL) + { + TIFFErrorExtR(tif, module, "No space for LZW code table"); + return (0); + } + /* + * Pre-load the table. + */ + code = 255; + do + { + sp->dec_codetab[code].firstchar = (unsigned char)code; + sp->dec_codetab[code].value = (unsigned char)code; + sp->dec_codetab[code].repeated = true; + sp->dec_codetab[code].length = 1; + sp->dec_codetab[code].next = NULL; + } while (code--); + /* + * Zero-out the unused entries */ + /* Silence false positive */ + /* coverity[overrun-buffer-arg] */ + memset(&sp->dec_codetab[CODE_CLEAR], 0, + (CODE_FIRST - CODE_CLEAR) * sizeof(code_t)); + } + return (1); } /* * Setup state for decoding a strip. */ -static int -LZWPreDecode(TIFF* tif, uint16_t s) +static int LZWPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "LZWPreDecode"; - LZWCodecState *sp = DecoderState(tif); + static const char module[] = "LZWPreDecode"; + LZWCodecState *sp = DecoderState(tif); - (void) s; - assert(sp != NULL); - if( sp->dec_codetab == NULL ) - { - tif->tif_setupdecode( tif ); - if( sp->dec_codetab == NULL ) - return (0); - } + (void)s; + assert(sp != NULL); + if (sp->dec_codetab == NULL) + { + tif->tif_setupdecode(tif); + if (sp->dec_codetab == NULL) + return (0); + } - /* - * Check for old bit-reversed codes. - */ - if (tif->tif_rawcc >= 2 && - tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) { + /* + * Check for old bit-reversed codes. + */ + if (tif->tif_rawcc >= 2 && tif->tif_rawdata[0] == 0 && + (tif->tif_rawdata[1] & 0x1)) + { #ifdef LZW_COMPAT - if (!sp->dec_decode) { - TIFFWarningExtR(tif, module, - "Old-style LZW codes, convert file"); - /* - * Override default decoding methods with - * ones that deal with the old coding. - * Otherwise the predictor versions set - * above will call the compatibility routines - * through the dec_decode method. - */ - tif->tif_decoderow = LZWDecodeCompat; - tif->tif_decodestrip = LZWDecodeCompat; - tif->tif_decodetile = LZWDecodeCompat; - /* - * If doing horizontal differencing, must - * re-setup the predictor logic since we - * switched the basic decoder methods... - */ - (*tif->tif_setupdecode)(tif); - sp->dec_decode = LZWDecodeCompat; - } - sp->lzw_maxcode = MAXCODE(BITS_MIN); -#else /* !LZW_COMPAT */ - if (!sp->dec_decode) { - TIFFErrorExtR(tif, module, - "Old-style LZW codes not supported"); - sp->dec_decode = LZWDecode; - } - return (0); -#endif/* !LZW_COMPAT */ - } else { - sp->lzw_maxcode = MAXCODE(BITS_MIN)-1; - sp->dec_decode = LZWDecode; - } - sp->lzw_nbits = BITS_MIN; - sp->lzw_nextbits = 0; - sp->lzw_nextdata = 0; - - sp->dec_restart = 0; - sp->dec_nbitsmask = MAXCODE(BITS_MIN); - sp->dec_bitsleft = 0; - sp->old_tif_rawcc = 0; - sp->dec_free_entp = sp->dec_codetab - 1 ; // + CODE_FIRST; - /* - * Zero entries that are not yet filled in. We do - * this to guard against bogus input data that causes - * us to index into undefined entries. If you can - * come up with a way to safely bounds-check input codes - * while decoding then you can remove this operation. - */ - sp->dec_oldcodep = &sp->dec_codetab[0]; - sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1]; - sp->read_error = 0; - return (1); + if (!sp->dec_decode) + { + TIFFWarningExtR(tif, module, "Old-style LZW codes, convert file"); + /* + * Override default decoding methods with + * ones that deal with the old coding. + * Otherwise the predictor versions set + * above will call the compatibility routines + * through the dec_decode method. + */ + tif->tif_decoderow = LZWDecodeCompat; + tif->tif_decodestrip = LZWDecodeCompat; + tif->tif_decodetile = LZWDecodeCompat; + /* + * If doing horizontal differencing, must + * re-setup the predictor logic since we + * switched the basic decoder methods... + */ + (*tif->tif_setupdecode)(tif); + sp->dec_decode = LZWDecodeCompat; + } + sp->lzw_maxcode = MAXCODE(BITS_MIN); +#else /* !LZW_COMPAT */ + if (!sp->dec_decode) + { + TIFFErrorExtR(tif, module, "Old-style LZW codes not supported"); + sp->dec_decode = LZWDecode; + } + return (0); +#endif /* !LZW_COMPAT */ + } + else + { + sp->lzw_maxcode = MAXCODE(BITS_MIN) - 1; + sp->dec_decode = LZWDecode; + } + sp->lzw_nbits = BITS_MIN; + sp->lzw_nextbits = 0; + sp->lzw_nextdata = 0; + + sp->dec_restart = 0; + sp->dec_nbitsmask = MAXCODE(BITS_MIN); + sp->dec_bitsleft = 0; + sp->old_tif_rawcc = 0; + sp->dec_free_entp = sp->dec_codetab - 1; // + CODE_FIRST; + /* + * Zero entries that are not yet filled in. We do + * this to guard against bogus input data that causes + * us to index into undefined entries. If you can + * come up with a way to safely bounds-check input codes + * while decoding then you can remove this operation. + */ + sp->dec_oldcodep = &sp->dec_codetab[0]; + sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask - 1]; + sp->read_error = 0; + return (1); } /* @@ -319,396 +327,424 @@ LZWPreDecode(TIFF* tif, uint16_t s) /* Get the next 32 or 64-bit from the input data */ #ifdef WORDS_BIGENDIAN -# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)) +#define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)) #elif SIZEOF_WORDTYPE == 8 -# if defined(__GNUC__) && defined(__x86_64__) -# define GetNextData(nextdata, bp) nextdata = __builtin_bswap64(*(uint64_t*)(bp)) -# elif defined(_M_X64) -# define GetNextData(nextdata, bp) nextdata = _byteswap_uint64(*(uint64_t*)(bp)) -# elif defined(__GNUC__) -# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)); \ - nextdata = __builtin_bswap64(nextdata) -# else -# define GetNextData(nextdata, bp) nextdata = (((uint64_t)bp[0]) << 56) | \ - (((uint64_t)bp[1]) << 48) | \ - (((uint64_t)bp[2]) << 40) | \ - (((uint64_t)bp[3]) << 32) | \ - (((uint64_t)bp[4]) << 24) | \ - (((uint64_t)bp[5]) << 16) | \ - (((uint64_t)bp[6]) << 8) | \ - (((uint64_t)bp[7])) -# endif +#if defined(__GNUC__) && defined(__x86_64__) +#define GetNextData(nextdata, bp) \ + nextdata = __builtin_bswap64(*(uint64_t *)(bp)) +#elif defined(_M_X64) +#define GetNextData(nextdata, bp) nextdata = _byteswap_uint64(*(uint64_t *)(bp)) +#elif defined(__GNUC__) +#define GetNextData(nextdata, bp) \ + memcpy(&nextdata, bp, sizeof(nextdata)); \ + nextdata = __builtin_bswap64(nextdata) +#else +#define GetNextData(nextdata, bp) \ + nextdata = (((uint64_t)bp[0]) << 56) | (((uint64_t)bp[1]) << 48) | \ + (((uint64_t)bp[2]) << 40) | (((uint64_t)bp[3]) << 32) | \ + (((uint64_t)bp[4]) << 24) | (((uint64_t)bp[5]) << 16) | \ + (((uint64_t)bp[6]) << 8) | (((uint64_t)bp[7])) +#endif #elif SIZEOF_WORDTYPE == 4 -# if defined(__GNUC__) && defined(__i386__) -# define GetNextData(nextdata, bp) nextdata = __builtin_bswap32(*(uint32_t*)(bp)) -# elif defined(_M_X86) -# define GetNextData(nextdata, bp) nextdata = _byteswap_ulong(*(unsigned long*)(bp)) -# elif defined(__GNUC__) -# define GetNextData(nextdata, bp) memcpy(&nextdata, bp, sizeof(nextdata)); \ - nextdata = __builtin_bswap32(nextdata) -# else -# define GetNextData(nextdata, bp) nextdata = (((uint32_t)bp[0]) << 24) | \ - (((uint32_t)bp[1]) << 16) | \ - (((uint32_t)bp[2]) << 8) | \ - (((uint32_t)bp[3])) -# endif +#if defined(__GNUC__) && defined(__i386__) +#define GetNextData(nextdata, bp) \ + nextdata = __builtin_bswap32(*(uint32_t *)(bp)) +#elif defined(_M_X86) +#define GetNextData(nextdata, bp) \ + nextdata = _byteswap_ulong(*(unsigned long *)(bp)) +#elif defined(__GNUC__) +#define GetNextData(nextdata, bp) \ + memcpy(&nextdata, bp, sizeof(nextdata)); \ + nextdata = __builtin_bswap32(nextdata) #else -# error "Unhandled SIZEOF_WORDTYPE" +#define GetNextData(nextdata, bp) \ + nextdata = (((uint32_t)bp[0]) << 24) | (((uint32_t)bp[1]) << 16) | \ + (((uint32_t)bp[2]) << 8) | (((uint32_t)bp[3])) +#endif +#else +#error "Unhandled SIZEOF_WORDTYPE" #endif -#define GetNextCodeLZW() do { \ - nextbits -= nbits; \ - if (nextbits < 0) { \ - if (dec_bitsleft >= 8 * SIZEOF_WORDTYPE) { \ - unsigned codetmp = (unsigned)(nextdata << (-nextbits)); \ - GetNextData(nextdata, bp); \ - bp += SIZEOF_WORDTYPE; \ - nextbits += 8 * SIZEOF_WORDTYPE; \ - dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \ - code = (WordType)((codetmp | (nextdata >> nextbits)) & nbitsmask); \ - break; \ - } \ - else {\ - if( dec_bitsleft < 8) { \ - goto no_eoi; \ - }\ - nextdata = (nextdata<<8) | *(bp)++; \ - nextbits += 8; \ - dec_bitsleft -= 8; \ - if( nextbits < 0 ) { \ - if( dec_bitsleft < 8) { \ - goto no_eoi; \ - }\ - nextdata = (nextdata<<8) | *(bp)++; \ - nextbits += 8; \ - dec_bitsleft -= 8; \ - } \ - } \ - } \ - code = (WordType)((nextdata >> nextbits) & nbitsmask); \ -} while(0) - -static int -LZWDecode(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) +#define GetNextCodeLZW() \ + do \ + { \ + nextbits -= nbits; \ + if (nextbits < 0) \ + { \ + if (dec_bitsleft >= 8 * SIZEOF_WORDTYPE) \ + { \ + unsigned codetmp = (unsigned)(nextdata << (-nextbits)); \ + GetNextData(nextdata, bp); \ + bp += SIZEOF_WORDTYPE; \ + nextbits += 8 * SIZEOF_WORDTYPE; \ + dec_bitsleft -= 8 * SIZEOF_WORDTYPE; \ + code = (WordType)((codetmp | (nextdata >> nextbits)) & \ + nbitsmask); \ + break; \ + } \ + else \ + { \ + if (dec_bitsleft < 8) \ + { \ + goto no_eoi; \ + } \ + nextdata = (nextdata << 8) | *(bp)++; \ + nextbits += 8; \ + dec_bitsleft -= 8; \ + if (nextbits < 0) \ + { \ + if (dec_bitsleft < 8) \ + { \ + goto no_eoi; \ + } \ + nextdata = (nextdata << 8) | *(bp)++; \ + nextbits += 8; \ + dec_bitsleft -= 8; \ + } \ + } \ + } \ + code = (WordType)((nextdata >> nextbits) & nbitsmask); \ + } while (0) + +static int LZWDecode(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) { - static const char module[] = "LZWDecode"; - LZWCodecState *sp = DecoderState(tif); - uint8_t *op = (uint8_t*) op0; - tmsize_t occ = occ0; - uint8_t *bp; - long nbits, nextbits, nbitsmask; - WordType nextdata; - code_t *free_entp, *maxcodep, *oldcodep; - - (void) s; - assert(sp != NULL); - assert(sp->dec_codetab != NULL); - - if (sp->read_error) { - return 0; - } - - /* - * Restart interrupted output operation. - */ - if (sp->dec_restart) { - tmsize_t residue; - - code_t* codep = sp->dec_codep; - residue = codep->length - sp->dec_restart; - if (residue > occ) { - /* - * Residue from previous decode is sufficient - * to satisfy decode request. Skip to the - * start of the decoded string, place decoded - * values in the output buffer, and return. - */ - sp->dec_restart += occ; - do { - codep = codep->next; - } while (--residue > occ && codep); - if (codep) { - uint8_t* tp = op + occ; - do { - *--tp = codep->value; - codep = codep->next; - } while (--occ && codep); - } - return (1); - } - /* - * Residue satisfies only part of the decode request. - */ - op += residue; - occ -= residue; - uint8_t* tp = op; - do { - *--tp = codep->value; - codep = codep->next; - } while (--residue && codep); - sp->dec_restart = 0; - } - - bp = (uint8_t*)tif->tif_rawcp; - sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); - uint64_t dec_bitsleft = sp->dec_bitsleft; - nbits = sp->lzw_nbits; - nextdata = sp->lzw_nextdata; - nextbits = sp->lzw_nextbits; - nbitsmask = sp->dec_nbitsmask; - oldcodep = sp->dec_oldcodep; - free_entp = sp->dec_free_entp; - maxcodep = sp->dec_maxcodep; - code_t* const dec_codetab = sp->dec_codetab; - code_t* codep; - - if (occ == 0) { - goto after_loop; + static const char module[] = "LZWDecode"; + LZWCodecState *sp = DecoderState(tif); + uint8_t *op = (uint8_t *)op0; + tmsize_t occ = occ0; + uint8_t *bp; + long nbits, nextbits, nbitsmask; + WordType nextdata; + code_t *free_entp, *maxcodep, *oldcodep; + + (void)s; + assert(sp != NULL); + assert(sp->dec_codetab != NULL); + + if (sp->read_error) + { + return 0; } -begin: + /* + * Restart interrupted output operation. + */ + if (sp->dec_restart) { - WordType code; - GetNextCodeLZW(); - codep = dec_codetab + code; - if (code >= CODE_FIRST) - goto code_above_or_equal_to_258; - if (code < 256) - goto code_below_256; - if (code == CODE_EOI) - goto after_loop; - goto code_clear; - -code_below_256: - { - if (codep > free_entp) - goto error_code; - free_entp->next = oldcodep; - free_entp->firstchar = oldcodep->firstchar; - free_entp->length = oldcodep->length+1; - free_entp->value = (uint8_t)code; - free_entp->repeated = (bool)(oldcodep->repeated & (oldcodep->value == code)); - if (++free_entp > maxcodep) { - if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ - nbits = BITS_MAX; - nbitsmask = MAXCODE(nbits); - maxcodep = dec_codetab + nbitsmask-1; - if( free_entp >= &dec_codetab[CSIZE] ) - { - /* At that point, the next valid states are either EOI or a */ - /* CODE_CLEAR. If a regular code is read, at the next */ - /* attempt at registering a new entry, we will error out */ - /* due to setting free_entp before any valid code */ - free_entp = dec_codetab - 1; - } - } - oldcodep = codep; - *op++ = (uint8_t)code; - occ--; - if (occ == 0) - goto after_loop; - goto begin; - } + tmsize_t residue; -code_above_or_equal_to_258: + code_t *codep = sp->dec_codep; + residue = codep->length - sp->dec_restart; + if (residue > occ) { /* - * Add the new entry to the code table. + * Residue from previous decode is sufficient + * to satisfy decode request. Skip to the + * start of the decoded string, place decoded + * values in the output buffer, and return. */ - - if (codep >= free_entp) + sp->dec_restart += occ; + do { - if (codep != free_entp) - goto error_code; - free_entp->value = oldcodep->firstchar; - } - else + codep = codep->next; + } while (--residue > occ && codep); + if (codep) { - free_entp->value = codep->firstchar; - } - free_entp->repeated = (bool)(oldcodep->repeated & (oldcodep->value == free_entp->value)); - free_entp->next = oldcodep; - - free_entp->firstchar = oldcodep->firstchar; - free_entp->length = oldcodep->length+1; - if (++free_entp > maxcodep) { - if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ - nbits = BITS_MAX; - nbitsmask = MAXCODE(nbits); - maxcodep = dec_codetab + nbitsmask-1; - if (free_entp >= &dec_codetab[CSIZE]) + uint8_t *tp = op + occ; + do { - /* At that point, the next valid states are either EOI or a */ - /* CODE_CLEAR. If a regular code is read, at the next */ - /* attempt at registering a new entry, we will error out */ - /* due to setting free_entp before any valid code */ - free_entp = dec_codetab - 1; - } + *--tp = codep->value; + codep = codep->next; + } while (--occ && codep); } - oldcodep = codep; + return (1); + } + /* + * Residue satisfies only part of the decode request. + */ + op += residue; + occ -= residue; + uint8_t *tp = op; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--residue && codep); + sp->dec_restart = 0; + } - /* - * Code maps to a string, copy string - * value to output (written in reverse). - */ - /* tiny bit faster on x86_64 to store in unsigned short than int */ - unsigned short len = codep->length; + bp = (uint8_t *)tif->tif_rawcp; + sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); + uint64_t dec_bitsleft = sp->dec_bitsleft; + nbits = sp->lzw_nbits; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + nbitsmask = sp->dec_nbitsmask; + oldcodep = sp->dec_oldcodep; + free_entp = sp->dec_free_entp; + maxcodep = sp->dec_maxcodep; + code_t *const dec_codetab = sp->dec_codetab; + code_t *codep; + + if (occ == 0) + { + goto after_loop; + } - if (len < 3) /* equivalent to len == 2 given all other conditions */ - { - if (occ <= 2) - { - if (occ == 2) - { - memcpy(op, &(codep->firstchar), 2); - op += 2; - occ -= 2; - goto after_loop; - } - goto too_short_buffer; - } +begin: +{ + WordType code; + GetNextCodeLZW(); + codep = dec_codetab + code; + if (code >= CODE_FIRST) + goto code_above_or_equal_to_258; + if (code < 256) + goto code_below_256; + if (code == CODE_EOI) + goto after_loop; + goto code_clear; + +code_below_256: +{ + if (codep > free_entp) + goto error_code; + free_entp->next = oldcodep; + free_entp->firstchar = oldcodep->firstchar; + free_entp->length = oldcodep->length + 1; + free_entp->value = (uint8_t)code; + free_entp->repeated = + (bool)(oldcodep->repeated & (oldcodep->value == code)); + if (++free_entp > maxcodep) + { + if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = dec_codetab + nbitsmask - 1; + if (free_entp >= &dec_codetab[CSIZE]) + { + /* At that point, the next valid states are either EOI or a */ + /* CODE_CLEAR. If a regular code is read, at the next */ + /* attempt at registering a new entry, we will error out */ + /* due to setting free_entp before any valid code */ + free_entp = dec_codetab - 1; + } + } + oldcodep = codep; + *op++ = (uint8_t)code; + occ--; + if (occ == 0) + goto after_loop; + goto begin; +} + +code_above_or_equal_to_258: +{ + /* + * Add the new entry to the code table. + */ + + if (codep >= free_entp) + { + if (codep != free_entp) + goto error_code; + free_entp->value = oldcodep->firstchar; + } + else + { + free_entp->value = codep->firstchar; + } + free_entp->repeated = + (bool)(oldcodep->repeated & (oldcodep->value == free_entp->value)); + free_entp->next = oldcodep; + + free_entp->firstchar = oldcodep->firstchar; + free_entp->length = oldcodep->length + 1; + if (++free_entp > maxcodep) + { + if (++nbits > BITS_MAX) /* should not happen for a conformant encoder */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = dec_codetab + nbitsmask - 1; + if (free_entp >= &dec_codetab[CSIZE]) + { + /* At that point, the next valid states are either EOI or a */ + /* CODE_CLEAR. If a regular code is read, at the next */ + /* attempt at registering a new entry, we will error out */ + /* due to setting free_entp before any valid code */ + free_entp = dec_codetab - 1; + } + } + oldcodep = codep; + + /* + * Code maps to a string, copy string + * value to output (written in reverse). + */ + /* tiny bit faster on x86_64 to store in unsigned short than int */ + unsigned short len = codep->length; + if (len < 3) /* equivalent to len == 2 given all other conditions */ + { + if (occ <= 2) + { + if (occ == 2) + { memcpy(op, &(codep->firstchar), 2); op += 2; occ -= 2; - goto begin; /* we can save the comparison occ > 0 */ + goto after_loop; } + goto too_short_buffer; + } - if (len == 3) - { - if (occ <= 3) - { - if (occ == 3) - { - op[0] = codep->firstchar; - op[1] = codep->next->value; - op[2] = codep->value; - op += 3; - occ -= 3; - goto after_loop; - } - goto too_short_buffer; - } + memcpy(op, &(codep->firstchar), 2); + op += 2; + occ -= 2; + goto begin; /* we can save the comparison occ > 0 */ + } + if (len == 3) + { + if (occ <= 3) + { + if (occ == 3) + { op[0] = codep->firstchar; op[1] = codep->next->value; op[2] = codep->value; op += 3; occ -= 3; - goto begin; /* we can save the comparison occ > 0 */ + goto after_loop; } + goto too_short_buffer; + } - if (len > occ) - { - goto too_short_buffer; - } + op[0] = codep->firstchar; + op[1] = codep->next->value; + op[2] = codep->value; + op += 3; + occ -= 3; + goto begin; /* we can save the comparison occ > 0 */ + } - if (codep->repeated) - { - memset(op, codep->value, len); - op += len; - occ -= len; - if (occ == 0) - goto after_loop; - goto begin; - } + if (len > occ) + { + goto too_short_buffer; + } - uint8_t* tp = op + len; + if (codep->repeated) + { + memset(op, codep->value, len); + op += len; + occ -= len; + if (occ == 0) + goto after_loop; + goto begin; + } - assert(len >= 4); + uint8_t *tp = op + len; - *--tp = codep->value; - codep = codep->next; - *--tp = codep->value; - codep = codep->next; - *--tp = codep->value; + assert(len >= 4); + + *--tp = codep->value; + codep = codep->next; + *--tp = codep->value; + codep = codep->next; + *--tp = codep->value; + codep = codep->next; + *--tp = codep->value; + if (tp > op) + { + do + { codep = codep->next; *--tp = codep->value; - if (tp > op) - { - do { - codep = codep->next; - *--tp = codep->value; - } while (tp > op); - } + } while (tp > op); + } - assert(occ >= len); - op += len; - occ -= len; - if (occ == 0) - goto after_loop; - goto begin; - } + assert(occ >= len); + op += len; + occ -= len; + if (occ == 0) + goto after_loop; + goto begin; +} code_clear: - { - free_entp = dec_codetab + CODE_FIRST; - nbits = BITS_MIN; - nbitsmask = MAXCODE(BITS_MIN); - maxcodep = dec_codetab + nbitsmask-1; - do { - GetNextCodeLZW(); - } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ - if (code == CODE_EOI) - goto after_loop; - if (code > CODE_EOI) { - goto error_code; - } - *op++ = (uint8_t)code; - occ--; - oldcodep = dec_codetab + code; - if (occ == 0) - goto after_loop; - goto begin; - } +{ + free_entp = dec_codetab + CODE_FIRST; + nbits = BITS_MIN; + nbitsmask = MAXCODE(BITS_MIN); + maxcodep = dec_codetab + nbitsmask - 1; + do + { + GetNextCodeLZW(); + } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ + if (code == CODE_EOI) + goto after_loop; + if (code > CODE_EOI) + { + goto error_code; } + *op++ = (uint8_t)code; + occ--; + oldcodep = dec_codetab + code; + if (occ == 0) + goto after_loop; + goto begin; +} +} too_short_buffer: +{ + /* + * String is too long for decode buffer, + * locate portion that will fit, copy to + * the decode buffer, and setup restart + * logic for the next decoding call. + */ + sp->dec_codep = codep; + do { - /* - * String is too long for decode buffer, - * locate portion that will fit, copy to - * the decode buffer, and setup restart - * logic for the next decoding call. - */ - sp->dec_codep = codep; - do { - codep = codep->next; - } while (codep->length > occ); + codep = codep->next; + } while (codep->length > occ); - sp->dec_restart = occ; - uint8_t* tp = op + occ; - do { - *--tp = codep->value; - codep = codep->next; - } while (--occ); - } + sp->dec_restart = occ; + uint8_t *tp = op + occ; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--occ); +} after_loop: - tif->tif_rawcc -= (tmsize_t)((uint8_t*) bp - tif->tif_rawcp ); - tif->tif_rawcp = (uint8_t*) bp; - sp->old_tif_rawcc = tif->tif_rawcc; - sp->dec_bitsleft = dec_bitsleft; - sp->lzw_nbits = (unsigned short) nbits; - sp->lzw_nextdata = nextdata; - sp->lzw_nextbits = nextbits; - sp->dec_nbitsmask = nbitsmask; - sp->dec_oldcodep = oldcodep; - sp->dec_free_entp = free_entp; - sp->dec_maxcodep = maxcodep; - - if (occ > 0) { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %"PRIu32" (short %"PRIu64" bytes)", - tif->tif_row, (uint64_t)occ); - return (0); - } - return (1); + tif->tif_rawcc -= (tmsize_t)((uint8_t *)bp - tif->tif_rawcp); + tif->tif_rawcp = (uint8_t *)bp; + sp->old_tif_rawcc = tif->tif_rawcc; + sp->dec_bitsleft = dec_bitsleft; + sp->lzw_nbits = (unsigned short)nbits; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->dec_nbitsmask = nbitsmask; + sp->dec_oldcodep = oldcodep; + sp->dec_free_entp = free_entp; + sp->dec_maxcodep = maxcodep; + + if (occ > 0) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %" PRIu32 " (short %" PRIu64 + " bytes)", + tif->tif_row, (uint64_t)occ); + return (0); + } + return (1); no_eoi: TIFFErrorExtR(tif, module, - "LZWDecode: Strip %"PRIu32" not terminated with EOI code", - tif->tif_curstrip); + "LZWDecode: Strip %" PRIu32 " not terminated with EOI code", + tif->tif_curstrip); return 0; error_code: sp->read_error = 1; @@ -722,227 +758,259 @@ error_code: * This check shouldn't be necessary because each * strip is suppose to be terminated with CODE_EOI. */ -#define NextCode(_tif, _sp, _bp, _code, _get, dec_bitsleft) { \ - if (dec_bitsleft < (uint64_t)nbits) { \ - TIFFWarningExtR(_tif, module, \ - "LZWDecode: Strip %"PRIu32" not terminated with EOI code", \ - _tif->tif_curstrip); \ - _code = CODE_EOI; \ - } else { \ - _get(_sp,_bp,_code); \ - dec_bitsleft -= nbits; \ - } \ -} +#define NextCode(_tif, _sp, _bp, _code, _get, dec_bitsleft) \ + { \ + if (dec_bitsleft < (uint64_t)nbits) \ + { \ + TIFFWarningExtR(_tif, module, \ + "LZWDecode: Strip %" PRIu32 \ + " not terminated with EOI code", \ + _tif->tif_curstrip); \ + _code = CODE_EOI; \ + } \ + else \ + { \ + _get(_sp, _bp, _code); \ + dec_bitsleft -= nbits; \ + } \ + } /* * Decode a "hunk of data" for old images. */ -#define GetNextCodeCompat(sp, bp, code) { \ - nextdata |= (unsigned long) *(bp)++ << nextbits; \ - nextbits += 8; \ - if (nextbits < nbits) { \ - nextdata |= (unsigned long) *(bp)++ << nextbits;\ - nextbits += 8; \ - } \ - code = (hcode_t)(nextdata & nbitsmask); \ - nextdata >>= nbits; \ - nextbits -= nbits; \ -} +#define GetNextCodeCompat(sp, bp, code) \ + { \ + nextdata |= (unsigned long)*(bp)++ << nextbits; \ + nextbits += 8; \ + if (nextbits < nbits) \ + { \ + nextdata |= (unsigned long)*(bp)++ << nextbits; \ + nextbits += 8; \ + } \ + code = (hcode_t)(nextdata & nbitsmask); \ + nextdata >>= nbits; \ + nextbits -= nbits; \ + } -static int -LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) +static int LZWDecodeCompat(TIFF *tif, uint8_t *op0, tmsize_t occ0, uint16_t s) { - static const char module[] = "LZWDecodeCompat"; - LZWCodecState *sp = DecoderState(tif); - uint8_t *op = (uint8_t*) op0; - tmsize_t occ = occ0; - uint8_t *tp; - uint8_t *bp; - int code, nbits; - int len; - long nextbits, nbitsmask; - WordType nextdata; - code_t *codep, *free_entp, *maxcodep, *oldcodep; - - (void) s; - assert(sp != NULL); - - /* - * Restart interrupted output operation. - */ - if (sp->dec_restart) { - tmsize_t residue; - - codep = sp->dec_codep; - residue = codep->length - sp->dec_restart; - if (residue > occ) { - /* - * Residue from previous decode is sufficient - * to satisfy decode request. Skip to the - * start of the decoded string, place decoded - * values in the output buffer, and return. - */ - sp->dec_restart += occ; - do { - codep = codep->next; - } while (--residue > occ); - tp = op + occ; - do { - *--tp = codep->value; - codep = codep->next; - } while (--occ); - return (1); - } - /* - * Residue satisfies only part of the decode request. - */ - op += residue; - occ -= residue; - tp = op; - do { - *--tp = codep->value; - codep = codep->next; - } while (--residue); - sp->dec_restart = 0; - } - - bp = (uint8_t*)tif->tif_rawcp; - - sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); - uint64_t dec_bitsleft = sp->dec_bitsleft; - - nbits = sp->lzw_nbits; - nextdata = sp->lzw_nextdata; - nextbits = sp->lzw_nextbits; - nbitsmask = sp->dec_nbitsmask; - oldcodep = sp->dec_oldcodep; - free_entp = sp->dec_free_entp; - maxcodep = sp->dec_maxcodep; - - while (occ > 0) { - NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft); - if (code == CODE_EOI) - break; - if (code == CODE_CLEAR) { - do { - free_entp = sp->dec_codetab + CODE_FIRST; - _TIFFmemset(free_entp, 0, - (CSIZE - CODE_FIRST) * sizeof (code_t)); - nbits = BITS_MIN; - nbitsmask = MAXCODE(BITS_MIN); - maxcodep = sp->dec_codetab + nbitsmask; - NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft); - } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ - if (code == CODE_EOI) - break; - if (code > CODE_CLEAR) { - TIFFErrorExtR(tif, tif->tif_name, - "LZWDecode: Corrupted LZW table at scanline %"PRIu32, - tif->tif_row); - return (0); - } - *op++ = (uint8_t)code; - occ--; - oldcodep = sp->dec_codetab + code; - continue; - } - codep = sp->dec_codetab + code; - - /* - * Add the new entry to the code table. - */ - if (free_entp < &sp->dec_codetab[0] || - free_entp >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExtR(tif, module, - "Corrupted LZW table at scanline %"PRIu32, tif->tif_row); - return (0); - } - - free_entp->next = oldcodep; - if (free_entp->next < &sp->dec_codetab[0] || - free_entp->next >= &sp->dec_codetab[CSIZE]) { - TIFFErrorExtR(tif, module, - "Corrupted LZW table at scanline %"PRIu32, tif->tif_row); - return (0); - } - free_entp->firstchar = free_entp->next->firstchar; - free_entp->length = free_entp->next->length+1; - free_entp->value = (codep < free_entp) ? - codep->firstchar : free_entp->firstchar; - if (++free_entp > maxcodep) { - if (++nbits > BITS_MAX) /* should not happen */ - nbits = BITS_MAX; - nbitsmask = MAXCODE(nbits); - maxcodep = sp->dec_codetab + nbitsmask; - } - oldcodep = codep; - if (code >= 256) { - /* - * Code maps to a string, copy string - * value to output (written in reverse). - */ - if(codep->length == 0) { - TIFFErrorExtR(tif, module, - "Wrong length of decoded " - "string: data probably corrupted at scanline %"PRIu32, - tif->tif_row); - return (0); - } - if (codep->length > occ) { - /* - * String is too long for decode buffer, - * locate portion that will fit, copy to - * the decode buffer, and setup restart - * logic for the next decoding call. - */ - sp->dec_codep = codep; - do { - codep = codep->next; - } while (codep->length > occ); - sp->dec_restart = occ; - tp = op + occ; - do { - *--tp = codep->value; - codep = codep->next; - } while (--occ); - break; - } - len = codep->length; - tp = op + len; - do { - *--tp = codep->value; - codep = codep->next; - } while (codep && tp > op); - assert(occ >= len); - op += len; - occ -= len; - } else { - *op++ = (uint8_t)code; - occ--; - } - } - - tif->tif_rawcc -= (tmsize_t)((uint8_t*) bp - tif->tif_rawcp ); - tif->tif_rawcp = (uint8_t*) bp; - - sp->old_tif_rawcc = tif->tif_rawcc; - sp->dec_bitsleft = dec_bitsleft; - - sp->lzw_nbits = (unsigned short)nbits; - sp->lzw_nextdata = nextdata; - sp->lzw_nextbits = nextbits; - sp->dec_nbitsmask = nbitsmask; - sp->dec_oldcodep = oldcodep; - sp->dec_free_entp = free_entp; - sp->dec_maxcodep = maxcodep; - - if (occ > 0) { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %"PRIu32" (short %"PRIu64" bytes)", - tif->tif_row, (uint64_t)occ); - return (0); - } - return (1); + static const char module[] = "LZWDecodeCompat"; + LZWCodecState *sp = DecoderState(tif); + uint8_t *op = (uint8_t *)op0; + tmsize_t occ = occ0; + uint8_t *tp; + uint8_t *bp; + int code, nbits; + int len; + long nextbits, nbitsmask; + WordType nextdata; + code_t *codep, *free_entp, *maxcodep, *oldcodep; + + (void)s; + assert(sp != NULL); + + /* + * Restart interrupted output operation. + */ + if (sp->dec_restart) + { + tmsize_t residue; + + codep = sp->dec_codep; + residue = codep->length - sp->dec_restart; + if (residue > occ) + { + /* + * Residue from previous decode is sufficient + * to satisfy decode request. Skip to the + * start of the decoded string, place decoded + * values in the output buffer, and return. + */ + sp->dec_restart += occ; + do + { + codep = codep->next; + } while (--residue > occ); + tp = op + occ; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--occ); + return (1); + } + /* + * Residue satisfies only part of the decode request. + */ + op += residue; + occ -= residue; + tp = op; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--residue); + sp->dec_restart = 0; + } + + bp = (uint8_t *)tif->tif_rawcp; + + sp->dec_bitsleft += (((uint64_t)tif->tif_rawcc - sp->old_tif_rawcc) << 3); + uint64_t dec_bitsleft = sp->dec_bitsleft; + + nbits = sp->lzw_nbits; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + nbitsmask = sp->dec_nbitsmask; + oldcodep = sp->dec_oldcodep; + free_entp = sp->dec_free_entp; + maxcodep = sp->dec_maxcodep; + + while (occ > 0) + { + NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft); + if (code == CODE_EOI) + break; + if (code == CODE_CLEAR) + { + do + { + free_entp = sp->dec_codetab + CODE_FIRST; + _TIFFmemset(free_entp, 0, + (CSIZE - CODE_FIRST) * sizeof(code_t)); + nbits = BITS_MIN; + nbitsmask = MAXCODE(BITS_MIN); + maxcodep = sp->dec_codetab + nbitsmask; + NextCode(tif, sp, bp, code, GetNextCodeCompat, dec_bitsleft); + } while (code == CODE_CLEAR); /* consecutive CODE_CLEAR codes */ + if (code == CODE_EOI) + break; + if (code > CODE_CLEAR) + { + TIFFErrorExtR( + tif, tif->tif_name, + "LZWDecode: Corrupted LZW table at scanline %" PRIu32, + tif->tif_row); + return (0); + } + *op++ = (uint8_t)code; + occ--; + oldcodep = sp->dec_codetab + code; + continue; + } + codep = sp->dec_codetab + code; + + /* + * Add the new entry to the code table. + */ + if (free_entp < &sp->dec_codetab[0] || + free_entp >= &sp->dec_codetab[CSIZE]) + { + TIFFErrorExtR(tif, module, + "Corrupted LZW table at scanline %" PRIu32, + tif->tif_row); + return (0); + } + + free_entp->next = oldcodep; + if (free_entp->next < &sp->dec_codetab[0] || + free_entp->next >= &sp->dec_codetab[CSIZE]) + { + TIFFErrorExtR(tif, module, + "Corrupted LZW table at scanline %" PRIu32, + tif->tif_row); + return (0); + } + free_entp->firstchar = free_entp->next->firstchar; + free_entp->length = free_entp->next->length + 1; + free_entp->value = + (codep < free_entp) ? codep->firstchar : free_entp->firstchar; + if (++free_entp > maxcodep) + { + if (++nbits > BITS_MAX) /* should not happen */ + nbits = BITS_MAX; + nbitsmask = MAXCODE(nbits); + maxcodep = sp->dec_codetab + nbitsmask; + } + oldcodep = codep; + if (code >= 256) + { + /* + * Code maps to a string, copy string + * value to output (written in reverse). + */ + if (codep->length == 0) + { + TIFFErrorExtR( + tif, module, + "Wrong length of decoded " + "string: data probably corrupted at scanline %" PRIu32, + tif->tif_row); + return (0); + } + if (codep->length > occ) + { + /* + * String is too long for decode buffer, + * locate portion that will fit, copy to + * the decode buffer, and setup restart + * logic for the next decoding call. + */ + sp->dec_codep = codep; + do + { + codep = codep->next; + } while (codep->length > occ); + sp->dec_restart = occ; + tp = op + occ; + do + { + *--tp = codep->value; + codep = codep->next; + } while (--occ); + break; + } + len = codep->length; + tp = op + len; + do + { + *--tp = codep->value; + codep = codep->next; + } while (codep && tp > op); + assert(occ >= len); + op += len; + occ -= len; + } + else + { + *op++ = (uint8_t)code; + occ--; + } + } + + tif->tif_rawcc -= (tmsize_t)((uint8_t *)bp - tif->tif_rawcp); + tif->tif_rawcp = (uint8_t *)bp; + + sp->old_tif_rawcc = tif->tif_rawcc; + sp->dec_bitsleft = dec_bitsleft; + + sp->lzw_nbits = (unsigned short)nbits; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->dec_nbitsmask = nbitsmask; + sp->dec_oldcodep = oldcodep; + sp->dec_free_entp = free_entp; + sp->dec_maxcodep = maxcodep; + + if (occ > 0) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %" PRIu32 " (short %" PRIu64 + " bytes)", + tif->tif_row, (uint64_t)occ); + return (0); + } + return (1); } #endif /* LZW_COMPAT */ @@ -950,77 +1018,80 @@ LZWDecodeCompat(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) * LZW Encoding. */ -static int -LZWSetupEncode(TIFF* tif) +static int LZWSetupEncode(TIFF *tif) { - static const char module[] = "LZWSetupEncode"; - LZWCodecState* sp = EncoderState(tif); - - assert(sp != NULL); - sp->enc_hashtab = (hash_t*) _TIFFmallocExt(tif, HSIZE*sizeof (hash_t)); - if (sp->enc_hashtab == NULL) { - TIFFErrorExtR(tif, module, - "No space for LZW hash table"); - return (0); - } - return (1); + static const char module[] = "LZWSetupEncode"; + LZWCodecState *sp = EncoderState(tif); + + assert(sp != NULL); + sp->enc_hashtab = (hash_t *)_TIFFmallocExt(tif, HSIZE * sizeof(hash_t)); + if (sp->enc_hashtab == NULL) + { + TIFFErrorExtR(tif, module, "No space for LZW hash table"); + return (0); + } + return (1); } /* * Reset encoding state at the start of a strip. */ -static int -LZWPreEncode(TIFF* tif, uint16_t s) +static int LZWPreEncode(TIFF *tif, uint16_t s) { - LZWCodecState *sp = EncoderState(tif); + LZWCodecState *sp = EncoderState(tif); - (void) s; - assert(sp != NULL); + (void)s; + assert(sp != NULL); - if( sp->enc_hashtab == NULL ) - { - tif->tif_setupencode( tif ); - } + if (sp->enc_hashtab == NULL) + { + tif->tif_setupencode(tif); + } - sp->lzw_nbits = BITS_MIN; - sp->lzw_maxcode = MAXCODE(BITS_MIN); - sp->lzw_free_ent = CODE_FIRST; - sp->lzw_nextbits = 0; - sp->lzw_nextdata = 0; - sp->enc_checkpoint = CHECK_GAP; - sp->enc_ratio = 0; - sp->enc_incount = 0; - sp->enc_outcount = 0; - /* - * The 4 here insures there is space for 2 max-sized - * codes in LZWEncode and LZWPostDecode. - */ - sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize-1 - 4; - cl_hash(sp); /* clear hash table */ - sp->enc_oldcode = (hcode_t) -1; /* generates CODE_CLEAR in LZWEncode */ - return (1); + sp->lzw_nbits = BITS_MIN; + sp->lzw_maxcode = MAXCODE(BITS_MIN); + sp->lzw_free_ent = CODE_FIRST; + sp->lzw_nextbits = 0; + sp->lzw_nextdata = 0; + sp->enc_checkpoint = CHECK_GAP; + sp->enc_ratio = 0; + sp->enc_incount = 0; + sp->enc_outcount = 0; + /* + * The 4 here insures there is space for 2 max-sized + * codes in LZWEncode and LZWPostDecode. + */ + sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize - 1 - 4; + cl_hash(sp); /* clear hash table */ + sp->enc_oldcode = (hcode_t)-1; /* generates CODE_CLEAR in LZWEncode */ + return (1); } -#define CALCRATIO(sp, rat) { \ - if (incount > 0x007fffff) { /* NB: shift will overflow */\ - rat = outcount >> 8; \ - rat = (rat == 0 ? 0x7fffffff : incount/rat); \ - } else \ - rat = (incount<<8) / outcount; \ -} +#define CALCRATIO(sp, rat) \ + { \ + if (incount > 0x007fffff) \ + { /* NB: shift will overflow */ \ + rat = outcount >> 8; \ + rat = (rat == 0 ? 0x7fffffff : incount / rat); \ + } \ + else \ + rat = (incount << 8) / outcount; \ + } /* Explicit 0xff masking to make icc -check=conversions happy */ -#define PutNextCode(op, c) { \ - nextdata = (nextdata << nbits) | c; \ - nextbits += nbits; \ - *op++ = (unsigned char)((nextdata >> (nextbits-8))&0xff); \ - nextbits -= 8; \ - if (nextbits >= 8) { \ - *op++ = (unsigned char)((nextdata >> (nextbits-8))&0xff); \ - nextbits -= 8; \ - } \ - outcount += nbits; \ -} +#define PutNextCode(op, c) \ + { \ + nextdata = (nextdata << nbits) | c; \ + nextbits += nbits; \ + *op++ = (unsigned char)((nextdata >> (nextbits - 8)) & 0xff); \ + nextbits -= 8; \ + if (nextbits >= 8) \ + { \ + *op++ = (unsigned char)((nextdata >> (nextbits - 8)) & 0xff); \ + nextbits -= 8; \ + } \ + outcount += nbits; \ + } /* * Encode a chunk of pixels. @@ -1036,308 +1107,327 @@ LZWPreEncode(TIFF* tif, uint16_t s) * are re-sized at this point, and a CODE_CLEAR is generated * for the decoder. */ -static int -LZWEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int LZWEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - register LZWCodecState *sp = EncoderState(tif); - register long fcode; - register hash_t *hp; - register int h, c; - hcode_t ent; - long disp; - tmsize_t incount, outcount, checkpoint; - WordType nextdata; - long nextbits; - int free_ent, maxcode, nbits; - uint8_t* op; - uint8_t* limit; - - (void) s; - if (sp == NULL) - return (0); - - assert(sp->enc_hashtab != NULL); - - /* - * Load local state. - */ - incount = sp->enc_incount; - outcount = sp->enc_outcount; - checkpoint = sp->enc_checkpoint; - nextdata = sp->lzw_nextdata; - nextbits = sp->lzw_nextbits; - free_ent = sp->lzw_free_ent; - maxcode = sp->lzw_maxcode; - nbits = sp->lzw_nbits; - op = tif->tif_rawcp; - limit = sp->enc_rawlimit; - ent = (hcode_t)sp->enc_oldcode; - - if (ent == (hcode_t) -1 && cc > 0) { - /* - * NB: This is safe because it can only happen - * at the start of a strip where we know there - * is space in the data buffer. - */ - PutNextCode(op, CODE_CLEAR); - ent = *bp++; cc--; incount++; - } - while (cc > 0) { - c = *bp++; cc--; incount++; - fcode = ((long)c << BITS_MAX) + ent; - h = (c << HSHIFT) ^ ent; /* xor hashing */ + register LZWCodecState *sp = EncoderState(tif); + register long fcode; + register hash_t *hp; + register int h, c; + hcode_t ent; + long disp; + tmsize_t incount, outcount, checkpoint; + WordType nextdata; + long nextbits; + int free_ent, maxcode, nbits; + uint8_t *op; + uint8_t *limit; + + (void)s; + if (sp == NULL) + return (0); + + assert(sp->enc_hashtab != NULL); + + /* + * Load local state. + */ + incount = sp->enc_incount; + outcount = sp->enc_outcount; + checkpoint = sp->enc_checkpoint; + nextdata = sp->lzw_nextdata; + nextbits = sp->lzw_nextbits; + free_ent = sp->lzw_free_ent; + maxcode = sp->lzw_maxcode; + nbits = sp->lzw_nbits; + op = tif->tif_rawcp; + limit = sp->enc_rawlimit; + ent = (hcode_t)sp->enc_oldcode; + + if (ent == (hcode_t)-1 && cc > 0) + { + /* + * NB: This is safe because it can only happen + * at the start of a strip where we know there + * is space in the data buffer. + */ + PutNextCode(op, CODE_CLEAR); + ent = *bp++; + cc--; + incount++; + } + while (cc > 0) + { + c = *bp++; + cc--; + incount++; + fcode = ((long)c << BITS_MAX) + ent; + h = (c << HSHIFT) ^ ent; /* xor hashing */ #ifdef _WINDOWS - /* - * Check hash index for an overflow. - */ - if (h >= HSIZE) - h -= HSIZE; + /* + * Check hash index for an overflow. + */ + if (h >= HSIZE) + h -= HSIZE; #endif - hp = &sp->enc_hashtab[h]; - if (hp->hash == fcode) { - ent = hp->code; - continue; - } - if (hp->hash >= 0) { - /* - * Primary hash failed, check secondary hash. - */ - disp = HSIZE - h; - if (h == 0) - disp = 1; - do { - /* - * Avoid pointer arithmetic because of - * wraparound problems with segments. - */ - if ((h -= disp) < 0) - h += HSIZE; - hp = &sp->enc_hashtab[h]; - if (hp->hash == fcode) { - ent = hp->code; - goto hit; - } - } while (hp->hash >= 0); - } - /* - * New entry, emit code and add to table. - */ - /* - * Verify there is space in the buffer for the code - * and any potential Clear code that might be emitted - * below. The value of limit is setup so that there - * are at least 4 bytes free--room for 2 codes. - */ - if (op > limit) { - tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - if( !TIFFFlushData1(tif) ) - return 0; - op = tif->tif_rawdata; - } - PutNextCode(op, ent); - ent = (hcode_t)c; - hp->code = (hcode_t)(free_ent++); - hp->hash = fcode; - if (free_ent == CODE_MAX-1) { - /* table is full, emit clear code and reset */ - cl_hash(sp); - sp->enc_ratio = 0; - incount = 0; - outcount = 0; - free_ent = CODE_FIRST; - PutNextCode(op, CODE_CLEAR); - nbits = BITS_MIN; - maxcode = MAXCODE(BITS_MIN); - } else { - /* - * If the next entry is going to be too big for - * the code size, then increase it, if possible. - */ - if (free_ent > maxcode) { - nbits++; - assert(nbits <= BITS_MAX); - maxcode = (int) MAXCODE(nbits); - } else if (incount >= checkpoint) { - tmsize_t rat; - /* - * Check compression ratio and, if things seem - * to be slipping, clear the hash table and - * reset state. The compression ratio is a - * 24+8-bit fractional number. - */ - checkpoint = incount+CHECK_GAP; - CALCRATIO(sp, rat); - if (rat <= sp->enc_ratio) { - cl_hash(sp); - sp->enc_ratio = 0; - incount = 0; - outcount = 0; - free_ent = CODE_FIRST; - PutNextCode(op, CODE_CLEAR); - nbits = BITS_MIN; - maxcode = MAXCODE(BITS_MIN); - } else - sp->enc_ratio = rat; - } - } - hit: - ; - } - - /* - * Restore global state. - */ - sp->enc_incount = incount; - sp->enc_outcount = outcount; - sp->enc_checkpoint = checkpoint; - sp->enc_oldcode = ent; - sp->lzw_nextdata = nextdata; - sp->lzw_nextbits = nextbits; - sp->lzw_free_ent = (unsigned short)free_ent; - sp->lzw_maxcode = (unsigned short)maxcode; - sp->lzw_nbits = (unsigned short)nbits; - tif->tif_rawcp = op; - return (1); + hp = &sp->enc_hashtab[h]; + if (hp->hash == fcode) + { + ent = hp->code; + continue; + } + if (hp->hash >= 0) + { + /* + * Primary hash failed, check secondary hash. + */ + disp = HSIZE - h; + if (h == 0) + disp = 1; + do + { + /* + * Avoid pointer arithmetic because of + * wraparound problems with segments. + */ + if ((h -= disp) < 0) + h += HSIZE; + hp = &sp->enc_hashtab[h]; + if (hp->hash == fcode) + { + ent = hp->code; + goto hit; + } + } while (hp->hash >= 0); + } + /* + * New entry, emit code and add to table. + */ + /* + * Verify there is space in the buffer for the code + * and any potential Clear code that might be emitted + * below. The value of limit is setup so that there + * are at least 4 bytes free--room for 2 codes. + */ + if (op > limit) + { + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + if (!TIFFFlushData1(tif)) + return 0; + op = tif->tif_rawdata; + } + PutNextCode(op, ent); + ent = (hcode_t)c; + hp->code = (hcode_t)(free_ent++); + hp->hash = fcode; + if (free_ent == CODE_MAX - 1) + { + /* table is full, emit clear code and reset */ + cl_hash(sp); + sp->enc_ratio = 0; + incount = 0; + outcount = 0; + free_ent = CODE_FIRST; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + maxcode = MAXCODE(BITS_MIN); + } + else + { + /* + * If the next entry is going to be too big for + * the code size, then increase it, if possible. + */ + if (free_ent > maxcode) + { + nbits++; + assert(nbits <= BITS_MAX); + maxcode = (int)MAXCODE(nbits); + } + else if (incount >= checkpoint) + { + tmsize_t rat; + /* + * Check compression ratio and, if things seem + * to be slipping, clear the hash table and + * reset state. The compression ratio is a + * 24+8-bit fractional number. + */ + checkpoint = incount + CHECK_GAP; + CALCRATIO(sp, rat); + if (rat <= sp->enc_ratio) + { + cl_hash(sp); + sp->enc_ratio = 0; + incount = 0; + outcount = 0; + free_ent = CODE_FIRST; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + maxcode = MAXCODE(BITS_MIN); + } + else + sp->enc_ratio = rat; + } + } + hit:; + } + + /* + * Restore global state. + */ + sp->enc_incount = incount; + sp->enc_outcount = outcount; + sp->enc_checkpoint = checkpoint; + sp->enc_oldcode = ent; + sp->lzw_nextdata = nextdata; + sp->lzw_nextbits = nextbits; + sp->lzw_free_ent = (unsigned short)free_ent; + sp->lzw_maxcode = (unsigned short)maxcode; + sp->lzw_nbits = (unsigned short)nbits; + tif->tif_rawcp = op; + return (1); } /* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ -static int -LZWPostEncode(TIFF* tif) +static int LZWPostEncode(TIFF *tif) { - register LZWCodecState *sp = EncoderState(tif); - uint8_t* op = tif->tif_rawcp; - long nextbits = sp->lzw_nextbits; - WordType nextdata = sp->lzw_nextdata; - tmsize_t outcount = sp->enc_outcount; - int nbits = sp->lzw_nbits; - - if (op > sp->enc_rawlimit) { - tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - if( !TIFFFlushData1(tif) ) - return 0; - op = tif->tif_rawdata; - } - if (sp->enc_oldcode != (hcode_t) -1) { - int free_ent = sp->lzw_free_ent; - - PutNextCode(op, sp->enc_oldcode); - sp->enc_oldcode = (hcode_t) -1; - free_ent ++; - - if (free_ent == CODE_MAX-1) { - /* table is full, emit clear code and reset */ - outcount = 0; - PutNextCode(op, CODE_CLEAR); - nbits = BITS_MIN; - } else { - /* - * If the next entry is going to be too big for - * the code size, then increase it, if possible. - */ - if (free_ent > sp->lzw_maxcode) { - nbits++; - assert(nbits <= BITS_MAX); - } - } - } - PutNextCode(op, CODE_EOI); - /* Explicit 0xff masking to make icc -check=conversions happy */ - if (nextbits > 0) - *op++ = (unsigned char)((nextdata << (8-nextbits))&0xff); - tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); - (void)outcount; - return (1); + register LZWCodecState *sp = EncoderState(tif); + uint8_t *op = tif->tif_rawcp; + long nextbits = sp->lzw_nextbits; + WordType nextdata = sp->lzw_nextdata; + tmsize_t outcount = sp->enc_outcount; + int nbits = sp->lzw_nbits; + + if (op > sp->enc_rawlimit) + { + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + if (!TIFFFlushData1(tif)) + return 0; + op = tif->tif_rawdata; + } + if (sp->enc_oldcode != (hcode_t)-1) + { + int free_ent = sp->lzw_free_ent; + + PutNextCode(op, sp->enc_oldcode); + sp->enc_oldcode = (hcode_t)-1; + free_ent++; + + if (free_ent == CODE_MAX - 1) + { + /* table is full, emit clear code and reset */ + outcount = 0; + PutNextCode(op, CODE_CLEAR); + nbits = BITS_MIN; + } + else + { + /* + * If the next entry is going to be too big for + * the code size, then increase it, if possible. + */ + if (free_ent > sp->lzw_maxcode) + { + nbits++; + assert(nbits <= BITS_MAX); + } + } + } + PutNextCode(op, CODE_EOI); + /* Explicit 0xff masking to make icc -check=conversions happy */ + if (nextbits > 0) + *op++ = (unsigned char)((nextdata << (8 - nextbits)) & 0xff); + tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata); + (void)outcount; + return (1); } /* * Reset encoding hash table. */ -static void -cl_hash(LZWCodecState* sp) +static void cl_hash(LZWCodecState *sp) { - register hash_t *hp = &sp->enc_hashtab[HSIZE-1]; - register long i = HSIZE-8; - - do { - i -= 8; - hp[-7].hash = -1; - hp[-6].hash = -1; - hp[-5].hash = -1; - hp[-4].hash = -1; - hp[-3].hash = -1; - hp[-2].hash = -1; - hp[-1].hash = -1; - hp[ 0].hash = -1; - hp -= 8; - } while (i >= 0); - for (i += 8; i > 0; i--, hp--) - hp->hash = -1; + register hash_t *hp = &sp->enc_hashtab[HSIZE - 1]; + register long i = HSIZE - 8; + + do + { + i -= 8; + hp[-7].hash = -1; + hp[-6].hash = -1; + hp[-5].hash = -1; + hp[-4].hash = -1; + hp[-3].hash = -1; + hp[-2].hash = -1; + hp[-1].hash = -1; + hp[0].hash = -1; + hp -= 8; + } while (i >= 0); + for (i += 8; i > 0; i--, hp--) + hp->hash = -1; } -static void -LZWCleanup(TIFF* tif) +static void LZWCleanup(TIFF *tif) { - (void)TIFFPredictorCleanup(tif); + (void)TIFFPredictorCleanup(tif); - assert(tif->tif_data != 0); + assert(tif->tif_data != 0); - if (DecoderState(tif)->dec_codetab) - _TIFFfreeExt(tif, DecoderState(tif)->dec_codetab); + if (DecoderState(tif)->dec_codetab) + _TIFFfreeExt(tif, DecoderState(tif)->dec_codetab); - if (EncoderState(tif)->enc_hashtab) - _TIFFfreeExt(tif, EncoderState(tif)->enc_hashtab); + if (EncoderState(tif)->enc_hashtab) + _TIFFfreeExt(tif, EncoderState(tif)->enc_hashtab); - _TIFFfreeExt(tif, tif->tif_data); - tif->tif_data = NULL; + _TIFFfreeExt(tif, tif->tif_data); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } -int -TIFFInitLZW(TIFF* tif, int scheme) +int TIFFInitLZW(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitLZW"; - (void)scheme; - assert(scheme == COMPRESSION_LZW); - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t*) _TIFFmallocExt(tif, sizeof (LZWCodecState)); - if (tif->tif_data == NULL) - goto bad; - DecoderState(tif)->dec_codetab = NULL; - DecoderState(tif)->dec_decode = NULL; - EncoderState(tif)->enc_hashtab = NULL; - LZWState(tif)->rw_mode = tif->tif_mode; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = LZWFixupTags; - tif->tif_setupdecode = LZWSetupDecode; - tif->tif_predecode = LZWPreDecode; - tif->tif_decoderow = LZWDecode; - tif->tif_decodestrip = LZWDecode; - tif->tif_decodetile = LZWDecode; - tif->tif_setupencode = LZWSetupEncode; - tif->tif_preencode = LZWPreEncode; - tif->tif_postencode = LZWPostEncode; - tif->tif_encoderow = LZWEncode; - tif->tif_encodestrip = LZWEncode; - tif->tif_encodetile = LZWEncode; - tif->tif_cleanup = LZWCleanup; - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); - return (1); + static const char module[] = "TIFFInitLZW"; + (void)scheme; + assert(scheme == COMPRESSION_LZW); + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(LZWCodecState)); + if (tif->tif_data == NULL) + goto bad; + DecoderState(tif)->dec_codetab = NULL; + DecoderState(tif)->dec_decode = NULL; + EncoderState(tif)->enc_hashtab = NULL; + LZWState(tif)->rw_mode = tif->tif_mode; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = LZWFixupTags; + tif->tif_setupdecode = LZWSetupDecode; + tif->tif_predecode = LZWPreDecode; + tif->tif_decoderow = LZWDecode; + tif->tif_decodestrip = LZWDecode; + tif->tif_decodetile = LZWDecode; + tif->tif_setupencode = LZWSetupEncode; + tif->tif_preencode = LZWPreEncode; + tif->tif_postencode = LZWPostEncode; + tif->tif_encoderow = LZWEncode; + tif->tif_encodestrip = LZWEncode; + tif->tif_encodetile = LZWEncode; + tif->tif_cleanup = LZWCleanup; + /* + * Setup predictor setup. + */ + (void)TIFFPredictorInit(tif); + return (1); bad: - TIFFErrorExtR(tif, module, - "No space for LZW state block"); - return (0); + TIFFErrorExtR(tif, module, "No space for LZW state block"); + return (0); } /* diff --git a/libtiff/tif_next.c b/libtiff/tif_next.c index 647c0a52..f000574e 100644 --- a/libtiff/tif_next.c +++ b/libtiff/tif_next.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -30,149 +30,165 @@ * NeXT 2-bit Grey Scale Compression Algorithm Support */ -#define SETPIXEL(op, v) { \ - switch (npixels++ & 3) { \ - case 0: op[0] = (unsigned char) ((v) << 6); break; \ - case 1: op[0] |= (v) << 4; break; \ - case 2: op[0] |= (v) << 2; break; \ - case 3: *op++ |= (v); op_offset++; break; \ - } \ -} +#define SETPIXEL(op, v) \ + { \ + switch (npixels++ & 3) \ + { \ + case 0: \ + op[0] = (unsigned char)((v) << 6); \ + break; \ + case 1: \ + op[0] |= (v) << 4; \ + break; \ + case 2: \ + op[0] |= (v) << 2; \ + break; \ + case 3: \ + *op++ |= (v); \ + op_offset++; \ + break; \ + } \ + } -#define LITERALROW 0x00 -#define LITERALSPAN 0x40 -#define WHITE ((1<<2)-1) +#define LITERALROW 0x00 +#define LITERALSPAN 0x40 +#define WHITE ((1 << 2) - 1) -static int -NeXTDecode(TIFF* tif, uint8_t* buf, tmsize_t occ, uint16_t s) +static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - static const char module[] = "NeXTDecode"; - unsigned char *bp, *op; - tmsize_t cc; - uint8_t* row; - tmsize_t scanline, n; + static const char module[] = "NeXTDecode"; + unsigned char *bp, *op; + tmsize_t cc; + uint8_t *row; + tmsize_t scanline, n; - (void) s; - /* - * Each scanline is assumed to start off as all - * white (we assume a PhotometricInterpretation - * of ``min-is-black''). - */ - for (op = (unsigned char*) buf, cc = occ; cc-- > 0;) - *op++ = 0xff; + (void)s; + /* + * Each scanline is assumed to start off as all + * white (we assume a PhotometricInterpretation + * of ``min-is-black''). + */ + for (op = (unsigned char *)buf, cc = occ; cc-- > 0;) + *op++ = 0xff; - bp = (unsigned char *)tif->tif_rawcp; - cc = tif->tif_rawcc; - scanline = tif->tif_scanlinesize; - if (occ % scanline) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (0); - } - for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) { - n = *bp++; - cc--; - switch (n) { - case LITERALROW: - /* - * The entire scanline is given as literal values. - */ - if (cc < scanline) - goto bad; - _TIFFmemcpy(row, bp, scanline); - bp += scanline; - cc -= scanline; - break; - case LITERALSPAN: { - tmsize_t off; - /* - * The scanline has a literal span that begins at some - * offset. - */ - if( cc < 4 ) - goto bad; - off = (bp[0] * 256) + bp[1]; - n = (bp[2] * 256) + bp[3]; - if (cc < 4+n || off+n > scanline) - goto bad; - _TIFFmemcpy(row+off, bp+4, n); - bp += 4+n; - cc -= 4+n; - break; - } - default: { - uint32_t npixels = 0, grey; - tmsize_t op_offset = 0; - uint32_t imagewidth = tif->tif_dir.td_imagewidth; - if( isTiled(tif) ) - imagewidth = tif->tif_dir.td_tilewidth; + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + scanline = tif->tif_scanlinesize; + if (occ % scanline) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (0); + } + for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) + { + n = *bp++; + cc--; + switch (n) + { + case LITERALROW: + /* + * The entire scanline is given as literal values. + */ + if (cc < scanline) + goto bad; + _TIFFmemcpy(row, bp, scanline); + bp += scanline; + cc -= scanline; + break; + case LITERALSPAN: + { + tmsize_t off; + /* + * The scanline has a literal span that begins at some + * offset. + */ + if (cc < 4) + goto bad; + off = (bp[0] * 256) + bp[1]; + n = (bp[2] * 256) + bp[3]; + if (cc < 4 + n || off + n > scanline) + goto bad; + _TIFFmemcpy(row + off, bp + 4, n); + bp += 4 + n; + cc -= 4 + n; + break; + } + default: + { + uint32_t npixels = 0, grey; + tmsize_t op_offset = 0; + uint32_t imagewidth = tif->tif_dir.td_imagewidth; + if (isTiled(tif)) + imagewidth = tif->tif_dir.td_tilewidth; - /* - * The scanline is composed of a sequence of constant - * color ``runs''. We shift into ``run mode'' and - * interpret bytes as codes of the form - * <color><npixels> until we've filled the scanline. - */ - op = row; - for (;;) { - grey = (uint32_t)((n >> 6) & 0x3); - n &= 0x3f; - /* - * Ensure the run does not exceed the scanline - * bounds, potentially resulting in a security - * issue. - */ - while (n-- > 0 && npixels < imagewidth && op_offset < scanline) - SETPIXEL(op, grey); - if (npixels >= imagewidth) - break; - if (op_offset >= scanline ) { - TIFFErrorExtR(tif, module, "Invalid data for scanline %"PRIu32, - tif->tif_row); - return (0); + /* + * The scanline is composed of a sequence of constant + * color ``runs''. We shift into ``run mode'' and + * interpret bytes as codes of the form + * <color><npixels> until we've filled the scanline. + */ + op = row; + for (;;) + { + grey = (uint32_t)((n >> 6) & 0x3); + n &= 0x3f; + /* + * Ensure the run does not exceed the scanline + * bounds, potentially resulting in a security + * issue. + */ + while (n-- > 0 && npixels < imagewidth && + op_offset < scanline) + SETPIXEL(op, grey); + if (npixels >= imagewidth) + break; + if (op_offset >= scanline) + { + TIFFErrorExtR(tif, module, + "Invalid data for scanline %" PRIu32, + tif->tif_row); + return (0); + } + if (cc == 0) + goto bad; + n = *bp++; + cc--; } - if (cc == 0) - goto bad; - n = *bp++; - cc--; - } - break; - } - } - } - tif->tif_rawcp = (uint8_t*) bp; - tif->tif_rawcc = cc; - return (1); + break; + } + } + } + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + return (1); bad: - TIFFErrorExtR(tif, module, "Not enough data for scanline %"PRIu32, - tif->tif_row); - return (0); + TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32, + tif->tif_row); + return (0); } -static int -NeXTPreDecode(TIFF* tif, uint16_t s) +static int NeXTPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "NeXTPreDecode"; - TIFFDirectory *td = &tif->tif_dir; - (void)s; + static const char module[] = "NeXTPreDecode"; + TIFFDirectory *td = &tif->tif_dir; + (void)s; - if( td->td_bitspersample != 2 ) - { - TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %"PRIu16, - td->td_bitspersample); - return (0); - } - return (1); + if (td->td_bitspersample != 2) + { + TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %" PRIu16, + td->td_bitspersample); + return (0); + } + return (1); } - -int -TIFFInitNeXT(TIFF* tif, int scheme) + +int TIFFInitNeXT(TIFF *tif, int scheme) { - (void) scheme; - tif->tif_predecode = NeXTPreDecode; - tif->tif_decoderow = NeXTDecode; - tif->tif_decodestrip = NeXTDecode; - tif->tif_decodetile = NeXTDecode; - return (1); + (void)scheme; + tif->tif_predecode = NeXTPreDecode; + tif->tif_decoderow = NeXTDecode; + tif->tif_decodestrip = NeXTDecode; + tif->tif_decodetile = NeXTDecode; + return (1); } #endif /* NEXT_SUPPORT */ diff --git a/libtiff/tif_ojpeg.c b/libtiff/tif_ojpeg.c index 23490af7..0c915de2 100644 --- a/libtiff/tif_ojpeg.c +++ b/libtiff/tif_ojpeg.c @@ -43,79 +43,83 @@ /* What is what, and what is not? - This decoder starts with an input stream, that is essentially the JpegInterchangeFormat - stream, if any, followed by the strile data, if any. This stream is read in - OJPEGReadByte and related functions. - - It analyzes the start of this stream, until it encounters non-marker data, i.e. - compressed image data. Some of the header markers it sees have no actual content, - like the SOI marker, and APP/COM markers that really shouldn't even be there. Some - other markers do have content, and the valuable bits and pieces of information - in these markers are saved, checking all to verify that the stream is more or - less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx + This decoder starts with an input stream, that is essentially the + JpegInterchangeFormat stream, if any, followed by the strile data, if any. + This stream is read in OJPEGReadByte and related functions. + + It analyzes the start of this stream, until it encounters non-marker data, + i.e. compressed image data. Some of the header markers it sees have no actual + content, like the SOI marker, and APP/COM markers that really shouldn't even + be there. Some other markers do have content, and the valuable bits and + pieces of information in these markers are saved, checking all to verify that + the stream is more or less within expected bounds. This happens inside the + OJPEGReadHeaderInfoSecStreamXxx functions. + + Some OJPEG imagery contains no valid JPEG header markers. This situation is + picked up on if we've seen no SOF marker when we're at the start of the + compressed image data. In this case, the tables are read from JpegXxxTables + tags, and the other bits and pieces of information is initialized to its most + basic value. This is implemented in the OJPEGReadHeaderInfoSecTablesXxx functions. - Some OJPEG imagery contains no valid JPEG header markers. This situation is picked - up on if we've seen no SOF marker when we're at the start of the compressed image - data. In this case, the tables are read from JpegXxxTables tags, and the other - bits and pieces of information is initialized to its most basic value. This is - implemented in the OJPEGReadHeaderInfoSecTablesXxx functions. - - When this is complete, a good and valid JPEG header can be assembled, and this is - passed through to LibJpeg. When that's done, the remainder of the input stream, i.e. - the compressed image data, can be passed through unchanged. This is done in - OJPEGWriteStream functions. - - LibTiff rightly expects to know the subsampling values before decompression. Just like - in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling - tag is notoriously unreliable. To correct these tag values with the ones inside - the JPEG stream, the first part of the input stream is pre-scanned in - OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings - or errors, up to the point where either these values are read, or it's clear they - aren't there. This means that some of the data is read twice, but we feel speed - in correcting these values is important enough to warrant this sacrifice. Although - there is currently no define or other configuration mechanism to disable this behavior, - the actual header scanning is build to robustly respond with error report if it - should encounter an uncorrected mismatch of subsampling values. See + When this is complete, a good and valid JPEG header can be assembled, and + this is passed through to LibJpeg. When that's done, the remainder of the + input stream, i.e. the compressed image data, can be passed through + unchanged. This is done in OJPEGWriteStream functions. + + LibTiff rightly expects to know the subsampling values before decompression. + Just like in new-style JPEG-in-TIFF, though, or even more so, actually, the + YCbCrsubsampling tag is notoriously unreliable. To correct these tag values + with the ones inside the JPEG stream, the first part of the input stream is + pre-scanned in OJPEGSubsamplingCorrect, making no note of any other data, + reporting no warnings or errors, up to the point where either these values + are read, or it's clear they aren't there. This means that some of the data + is read twice, but we feel speed in correcting these values is important + enough to warrant this sacrifice. Although there is currently no define or + other configuration mechanism to disable this behavior, the actual header + scanning is build to robustly respond with error report if it should + encounter an uncorrected mismatch of subsampling values. See OJPEGReadHeaderInfoSecStreamSof. - The restart interval and restart markers are the most tricky part... The restart - interval can be specified in a tag. It can also be set inside the input JPEG stream. - It can be used inside the input JPEG stream. If reading from strile data, we've - consistently discovered the need to insert restart markers in between the different - striles, as is also probably the most likely interpretation of the original TIFF 6.0 - specification. With all this setting of interval, and actual use of markers that is not - predictable at the time of valid JPEG header assembly, the restart thing may turn - out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors - succeed in reading back what they write, which may be the reason why we've been able - to discover ways that seem to work. - - Some special provision is made for planarconfig separate OJPEG files. These seem - to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS, - and plane. This may or may not be a valid JPEG configuration, we don't know and don't - care. We want LibTiff to be able to access the planes individually, without huge - buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this - case, that allow us to pass a single plane such that LibJpeg sees a valid - single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent - planes, is done inside OJPEGReadSecondarySos. - - The benefit of the scheme is... that it works, basically. We know of no other that - does. It works without checking software tag, or otherwise going about things in an - OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases - with and without JpegInterchangeFormat, with and without striles, with part of - the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving - and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out - of the data. - - Another nice side-effect is that a complete JPEG single valid stream is build if - planarconfig is not separate (vast majority). We may one day use that to build - converters to JPEG, and/or to new-style JPEG compression inside TIFF. - - A disadvantage is the lack of random access to the individual striles. This is the - reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode. - Applications would do well accessing all striles in order, as this will result in - a single sequential scan of the input stream, and no restarting of LibJpeg decoding - session. + The restart interval and restart markers are the most tricky part... The + restart interval can be specified in a tag. It can also be set inside the + input JPEG stream. It can be used inside the input JPEG stream. If reading + from strile data, we've consistently discovered the need to insert restart + markers in between the different striles, as is also probably the most likely + interpretation of the original TIFF 6.0 specification. With all this setting + of interval, and actual use of markers that is not predictable at the time of + valid JPEG header assembly, the restart thing may turn out the Achilles heel + of this implementation. Fortunately, most OJPEG writer vendors succeed in + reading back what they write, which may be the reason why we've been able to + discover ways that seem to work. + + Some special provision is made for planarconfig separate OJPEG files. These + seem to consistently contain header info, a SOS marker, a plane, SOS marker, + plane, SOS, and plane. This may or may not be a valid JPEG configuration, we + don't know and don't care. We want LibTiff to be able to access the planes + individually, without huge buffering inside LibJpeg, anyway. So we compose + headers to feed to LibJpeg, in this case, that allow us to pass a single + plane such that LibJpeg sees a valid single-channel JPEG stream. Locating + subsequent SOS markers, and thus subsequent planes, is done inside + OJPEGReadSecondarySos. + + The benefit of the scheme is... that it works, basically. We know of no other + that does. It works without checking software tag, or otherwise going about + things in an OJPEG flavor specific manner. Instead, it is a single scheme, + that covers the cases with and without JpegInterchangeFormat, with and + without striles, with part of the header in JpegInterchangeFormat and + remainder in first strile, etc. It is forgiving and robust, may likely work + with OJPEG flavors we've not seen yet, and makes most out of the data. + + Another nice side-effect is that a complete JPEG single valid stream is build + if planarconfig is not separate (vast majority). We may one day use that to + build converters to JPEG, and/or to new-style JPEG compression inside TIFF. + + A disadvantage is the lack of random access to the individual striles. This + is the reason for much of the complicated restart-and-position stuff inside + OJPEGPreDecode. Applications would do well accessing all striles in order, as + this will result in a single sequential scan of the input stream, and no + restarting of LibJpeg decoding session. */ #define WIN32_LEAN_AND_MEAN @@ -125,30 +129,31 @@ #ifdef OJPEG_SUPPORT /* Configuration defines here are: - * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments, - * like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to - * libjpeg, with longjump stuff, are encapsulated in dedicated functions. When - * JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external - * to this unit, and can be defined elsewhere to use stuff other then longjump. - * The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators - * here, internally, with normal longjump. - * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is - * conveniently available, but still it may be worthwhile to use _setjmp or sigsetjmp - * in place of plain setjmp. These macros will make it easier. It is useless - * to fiddle with these if you define JPEG_ENCAP_EXTERNAL. - * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee - * instant processing, optimal streaming and optimal use of processor cache, but also big - * enough so as to not result in significant call overhead. It should be at least a few - * bytes to accommodate some structures (this is verified in asserts), but it would not be - * sensible to make it this small anyway, and it should be at most 64K since it is indexed - * with uint16_t. We recommend 2K. - * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has - * absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly. + * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some + * environments, like eg LibTiffDelphi, this is not possible. For this reason, + * the actual calls to libjpeg, with longjump stuff, are encapsulated in + * dedicated functions. When JPEG_ENCAP_EXTERNAL is defined, these encapsulating + * functions are declared external to this unit, and can be defined elsewhere to + * use stuff other then longjump. The default mode, without JPEG_ENCAP_EXTERNAL, + * implements the call encapsulators here, internally, with normal longjump. + * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent + * is conveniently available, but still it may be worthwhile to use _setjmp or + * sigsetjmp in place of plain setjmp. These macros will make it easier. It is + * useless to fiddle with these if you define JPEG_ENCAP_EXTERNAL. OJPEG_BUFFER: + * Define the size of the desired buffer here. Should be small enough so as to + * guarantee instant processing, optimal streaming and optimal use of processor + * cache, but also big enough so as to not result in significant call overhead. + * It should be at least a few bytes to accommodate some structures (this is + * verified in asserts), but it would not be sensible to make it this small + * anyway, and it should be at most 64K since it is indexed with uint16_t. We + * recommend 2K. EGYPTIANWALK: You could also define EGYPTIANWALK here, but it + * is not used anywhere and has absolutely no effect. That is why most people + * insist the EGYPTIANWALK is a bit silly. */ /* define LIBJPEG_ENCAP_EXTERNAL */ #define SETJMP(jbuf) setjmp(jbuf) -#define LONGJMP(jbuf,code) longjmp(jbuf,code) +#define LONGJMP(jbuf, code) longjmp(jbuf, code) #define JMP_BUF jmp_buf #define OJPEG_BUFFER 2048 /* define EGYPTIANWALK */ @@ -166,22 +171,36 @@ #define JPEG_MARKER_APP0 0xE0 #define JPEG_MARKER_COM 0xFE -#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0) -#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1) -#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2) -#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3) -#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4) -#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5) -#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6) +#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC + 0) +#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC + 1) +#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC + 2) +#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC + 3) +#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC + 4) +#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC + 5) +#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC + 6) static const TIFFField ojpegFields[] = { - {TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat",NULL}, - {TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength",NULL}, - {TIFFTAG_JPEGQTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables",NULL}, - {TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables",NULL}, - {TIFFTAG_JPEGACTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables",NULL}, - {TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc",NULL}, - {TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval",NULL}, + {TIFFTAG_JPEGIFOFFSET, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, + TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGINTERCHANGEFORMAT, TRUE, FALSE, + "JpegInterchangeFormat", NULL}, + {TIFFTAG_JPEGIFBYTECOUNT, 1, 1, TIFF_LONG8, 0, TIFF_SETGET_UINT64, + TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH, TRUE, + FALSE, "JpegInterchangeFormatLength", NULL}, + {TIFFTAG_JPEGQTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0, + TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGQTABLES, + FALSE, TRUE, "JpegQTables", NULL}, + {TIFFTAG_JPEGDCTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0, + TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGDCTABLES, + FALSE, TRUE, "JpegDcTables", NULL}, + {TIFFTAG_JPEGACTABLES, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG8, 0, + TIFF_SETGET_C32_UINT64, TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGACTABLES, + FALSE, TRUE, "JpegAcTables", NULL}, + {TIFFTAG_JPEGPROC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGPROC, FALSE, FALSE, "JpegProc", + NULL}, + {TIFFTAG_JPEGRESTARTINTERVAL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UNDEFINED, FIELD_OJPEG_JPEGRESTARTINTERVAL, FALSE, FALSE, + "JpegRestartInterval", NULL}, }; #ifndef LIBJPEG_ENCAP_EXTERNAL @@ -201,2414 +220,2593 @@ static const TIFFField ojpegFields[] = { a conflicting typedef given the headers which are included. */ #if defined(__BORLANDC__) || defined(__MINGW32__) -# define XMD_H 1 +#define XMD_H 1 #endif /* Define "boolean" as unsigned char, not int, per Windows custom. */ #if defined(__WIN32__) && !defined(__MINGW32__) -# ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ - typedef unsigned char boolean; -# endif -# define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ +#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ #endif -#include "jpeglib.h" #include "jerror.h" +#include "jpeglib.h" typedef struct jpeg_error_mgr jpeg_error_mgr; typedef struct jpeg_common_struct jpeg_common_struct; typedef struct jpeg_decompress_struct jpeg_decompress_struct; typedef struct jpeg_source_mgr jpeg_source_mgr; -typedef enum { - osibsNotSetYet, - osibsJpegInterchangeFormat, - osibsStrile, - osibsEof +typedef enum +{ + osibsNotSetYet, + osibsJpegInterchangeFormat, + osibsStrile, + osibsEof } OJPEGStateInBufferSource; -typedef enum { - ososSoi, - ososQTable0,ososQTable1,ososQTable2,ososQTable3, - ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3, - ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3, - ososDri, - ososSof, - ososSos, - ososCompressed, - ososRst, - ososEoi +typedef enum +{ + ososSoi, + ososQTable0, + ososQTable1, + ososQTable2, + ososQTable3, + ososDcTable0, + ososDcTable1, + ososDcTable2, + ososDcTable3, + ososAcTable0, + ososAcTable1, + ososAcTable2, + ososAcTable3, + ososDri, + ososSof, + ososSos, + ososCompressed, + ososRst, + ososEoi } OJPEGStateOutState; -typedef struct { - TIFF* tif; - int decoder_ok; - int error_in_raw_data_decoding; - #ifndef LIBJPEG_ENCAP_EXTERNAL - JMP_BUF exit_jmpbuf; - #endif - TIFFVGetMethod vgetparent; - TIFFVSetMethod vsetparent; - TIFFPrintMethod printdir; - uint64_t file_size; - uint32_t image_width; - uint32_t image_length; - uint32_t strile_width; - uint32_t strile_length; - uint32_t strile_length_total; - uint8_t samples_per_pixel; - uint8_t plane_sample_offset; - uint8_t samples_per_pixel_per_plane; - uint64_t jpeg_interchange_format; - uint64_t jpeg_interchange_format_length; - uint8_t jpeg_proc; - uint8_t subsamplingcorrect; - uint8_t subsamplingcorrect_done; - uint8_t subsampling_tag; - uint8_t subsampling_hor; - uint8_t subsampling_ver; - uint8_t subsampling_force_desubsampling_inside_decompression; - uint8_t qtable_offset_count; - uint8_t dctable_offset_count; - uint8_t actable_offset_count; - uint64_t qtable_offset[3]; - uint64_t dctable_offset[3]; - uint64_t actable_offset[3]; - uint8_t* qtable[4]; - uint8_t* dctable[4]; - uint8_t* actable[4]; - uint16_t restart_interval; - uint8_t restart_index; - uint8_t sof_log; - uint8_t sof_marker_id; - uint32_t sof_x; - uint32_t sof_y; - uint8_t sof_c[3]; - uint8_t sof_hv[3]; - uint8_t sof_tq[3]; - uint8_t sos_cs[3]; - uint8_t sos_tda[3]; - struct { - uint8_t log; - OJPEGStateInBufferSource in_buffer_source; - uint32_t in_buffer_next_strile; - uint64_t in_buffer_file_pos; - uint64_t in_buffer_file_togo; - } sos_end[3]; - uint8_t readheader_done; - uint8_t writeheader_done; - uint16_t write_cursample; - uint32_t write_curstrile; - uint8_t libjpeg_session_active; - uint8_t libjpeg_jpeg_query_style; - jpeg_error_mgr libjpeg_jpeg_error_mgr; - jpeg_decompress_struct libjpeg_jpeg_decompress_struct; - jpeg_source_mgr libjpeg_jpeg_source_mgr; - uint8_t subsampling_convert_log; - uint32_t subsampling_convert_ylinelen; - uint32_t subsampling_convert_ylines; - uint32_t subsampling_convert_clinelen; - uint32_t subsampling_convert_clines; - uint32_t subsampling_convert_ybuflen; - uint32_t subsampling_convert_cbuflen; - uint32_t subsampling_convert_ycbcrbuflen; - uint8_t* subsampling_convert_ycbcrbuf; - uint8_t* subsampling_convert_ybuf; - uint8_t* subsampling_convert_cbbuf; - uint8_t* subsampling_convert_crbuf; - uint32_t subsampling_convert_ycbcrimagelen; - uint8_t** subsampling_convert_ycbcrimage; - uint32_t subsampling_convert_clinelenout; - uint32_t subsampling_convert_state; - uint32_t bytes_per_line; /* if the codec outputs subsampled data, a 'line' in bytes_per_line */ - uint32_t lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows */ - OJPEGStateInBufferSource in_buffer_source; - uint32_t in_buffer_next_strile; - uint32_t in_buffer_strile_count; - uint64_t in_buffer_file_pos; - uint8_t in_buffer_file_pos_log; - uint64_t in_buffer_file_togo; - uint16_t in_buffer_togo; - uint8_t* in_buffer_cur; - uint8_t in_buffer[OJPEG_BUFFER]; - OJPEGStateOutState out_state; - uint8_t out_buffer[OJPEG_BUFFER]; - uint8_t* skip_buffer; +typedef struct +{ + TIFF *tif; + int decoder_ok; + int error_in_raw_data_decoding; +#ifndef LIBJPEG_ENCAP_EXTERNAL + JMP_BUF exit_jmpbuf; +#endif + TIFFVGetMethod vgetparent; + TIFFVSetMethod vsetparent; + TIFFPrintMethod printdir; + uint64_t file_size; + uint32_t image_width; + uint32_t image_length; + uint32_t strile_width; + uint32_t strile_length; + uint32_t strile_length_total; + uint8_t samples_per_pixel; + uint8_t plane_sample_offset; + uint8_t samples_per_pixel_per_plane; + uint64_t jpeg_interchange_format; + uint64_t jpeg_interchange_format_length; + uint8_t jpeg_proc; + uint8_t subsamplingcorrect; + uint8_t subsamplingcorrect_done; + uint8_t subsampling_tag; + uint8_t subsampling_hor; + uint8_t subsampling_ver; + uint8_t subsampling_force_desubsampling_inside_decompression; + uint8_t qtable_offset_count; + uint8_t dctable_offset_count; + uint8_t actable_offset_count; + uint64_t qtable_offset[3]; + uint64_t dctable_offset[3]; + uint64_t actable_offset[3]; + uint8_t *qtable[4]; + uint8_t *dctable[4]; + uint8_t *actable[4]; + uint16_t restart_interval; + uint8_t restart_index; + uint8_t sof_log; + uint8_t sof_marker_id; + uint32_t sof_x; + uint32_t sof_y; + uint8_t sof_c[3]; + uint8_t sof_hv[3]; + uint8_t sof_tq[3]; + uint8_t sos_cs[3]; + uint8_t sos_tda[3]; + struct + { + uint8_t log; + OJPEGStateInBufferSource in_buffer_source; + uint32_t in_buffer_next_strile; + uint64_t in_buffer_file_pos; + uint64_t in_buffer_file_togo; + } sos_end[3]; + uint8_t readheader_done; + uint8_t writeheader_done; + uint16_t write_cursample; + uint32_t write_curstrile; + uint8_t libjpeg_session_active; + uint8_t libjpeg_jpeg_query_style; + jpeg_error_mgr libjpeg_jpeg_error_mgr; + jpeg_decompress_struct libjpeg_jpeg_decompress_struct; + jpeg_source_mgr libjpeg_jpeg_source_mgr; + uint8_t subsampling_convert_log; + uint32_t subsampling_convert_ylinelen; + uint32_t subsampling_convert_ylines; + uint32_t subsampling_convert_clinelen; + uint32_t subsampling_convert_clines; + uint32_t subsampling_convert_ybuflen; + uint32_t subsampling_convert_cbuflen; + uint32_t subsampling_convert_ycbcrbuflen; + uint8_t *subsampling_convert_ycbcrbuf; + uint8_t *subsampling_convert_ybuf; + uint8_t *subsampling_convert_cbbuf; + uint8_t *subsampling_convert_crbuf; + uint32_t subsampling_convert_ycbcrimagelen; + uint8_t **subsampling_convert_ycbcrimage; + uint32_t subsampling_convert_clinelenout; + uint32_t subsampling_convert_state; + uint32_t bytes_per_line; /* if the codec outputs subsampled data, a 'line' + in bytes_per_line */ + uint32_t lines_per_strile; /* and lines_per_strile means subsampling_ver + desubsampled rows */ + OJPEGStateInBufferSource in_buffer_source; + uint32_t in_buffer_next_strile; + uint32_t in_buffer_strile_count; + uint64_t in_buffer_file_pos; + uint8_t in_buffer_file_pos_log; + uint64_t in_buffer_file_togo; + uint16_t in_buffer_togo; + uint8_t *in_buffer_cur; + uint8_t in_buffer[OJPEG_BUFFER]; + OJPEGStateOutState out_state; + uint8_t out_buffer[OJPEG_BUFFER]; + uint8_t *skip_buffer; } OJPEGState; -static int OJPEGVGetField(TIFF* tif, uint32_t tag, va_list ap); -static int OJPEGVSetField(TIFF* tif, uint32_t tag, va_list ap); -static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags); - -static int OJPEGFixupTags(TIFF* tif); -static int OJPEGSetupDecode(TIFF* tif); -static int OJPEGPreDecode(TIFF* tif, uint16_t s); -static int OJPEGPreDecodeSkipRaw(TIFF* tif); -static int OJPEGPreDecodeSkipScanlines(TIFF* tif); -static int OJPEGDecode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s); -static int OJPEGDecodeRaw(TIFF* tif, uint8_t* buf, tmsize_t cc); -static int OJPEGDecodeScanlines(TIFF* tif, uint8_t* buf, tmsize_t cc); -static void OJPEGPostDecode(TIFF* tif, uint8_t* buf, tmsize_t cc); -static int OJPEGSetupEncode(TIFF* tif); -static int OJPEGPreEncode(TIFF* tif, uint16_t s); -static int OJPEGEncode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s); -static int OJPEGPostEncode(TIFF* tif); -static void OJPEGCleanup(TIFF* tif); - -static void OJPEGSubsamplingCorrect(TIFF* tif); -static int OJPEGReadHeaderInfo(TIFF* tif); -static int OJPEGReadSecondarySos(TIFF* tif, uint16_t s); -static int OJPEGWriteHeaderInfo(TIFF* tif); -static void OJPEGLibjpegSessionAbort(TIFF* tif); - -static int OJPEGReadHeaderInfoSec(TIFF* tif); -static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif); -static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif); -static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif); -static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8_t marker_id); -static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif); -static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif); -static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif); -static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif); - -static int OJPEGReadBufferFill(OJPEGState* sp); -static int OJPEGReadByte(OJPEGState* sp, uint8_t* byte); -static int OJPEGReadBytePeek(OJPEGState* sp, uint8_t* byte); -static void OJPEGReadByteAdvance(OJPEGState* sp); -static int OJPEGReadWord(OJPEGState* sp, uint16_t* word); -static int OJPEGReadBlock(OJPEGState* sp, uint16_t len, void* mem); -static void OJPEGReadSkip(OJPEGState* sp, uint16_t len); - -static int OJPEGWriteStream(TIFF* tif, void** mem, uint32_t* len); -static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32_t* len); -static void OJPEGWriteStreamQTable(TIFF* tif, uint8_t table_index, void** mem, uint32_t* len); -static void OJPEGWriteStreamDcTable(TIFF* tif, uint8_t table_index, void** mem, uint32_t* len); -static void OJPEGWriteStreamAcTable(TIFF* tif, uint8_t table_index, void** mem, uint32_t* len); -static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32_t* len); -static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32_t* len); -static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32_t* len); -static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32_t* len); -static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32_t* len); -static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32_t* len); +static int OJPEGVGetField(TIFF *tif, uint32_t tag, va_list ap); +static int OJPEGVSetField(TIFF *tif, uint32_t tag, va_list ap); +static void OJPEGPrintDir(TIFF *tif, FILE *fd, long flags); + +static int OJPEGFixupTags(TIFF *tif); +static int OJPEGSetupDecode(TIFF *tif); +static int OJPEGPreDecode(TIFF *tif, uint16_t s); +static int OJPEGPreDecodeSkipRaw(TIFF *tif); +static int OJPEGPreDecodeSkipScanlines(TIFF *tif); +static int OJPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc); +static int OJPEGDecodeScanlines(TIFF *tif, uint8_t *buf, tmsize_t cc); +static void OJPEGPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc); +static int OJPEGSetupEncode(TIFF *tif); +static int OJPEGPreEncode(TIFF *tif, uint16_t s); +static int OJPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s); +static int OJPEGPostEncode(TIFF *tif); +static void OJPEGCleanup(TIFF *tif); + +static void OJPEGSubsamplingCorrect(TIFF *tif); +static int OJPEGReadHeaderInfo(TIFF *tif); +static int OJPEGReadSecondarySos(TIFF *tif, uint16_t s); +static int OJPEGWriteHeaderInfo(TIFF *tif); +static void OJPEGLibjpegSessionAbort(TIFF *tif); + +static int OJPEGReadHeaderInfoSec(TIFF *tif); +static int OJPEGReadHeaderInfoSecStreamDri(TIFF *tif); +static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif); +static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif); +static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id); +static int OJPEGReadHeaderInfoSecStreamSos(TIFF *tif); +static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif); +static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif); +static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif); + +static int OJPEGReadBufferFill(OJPEGState *sp); +static int OJPEGReadByte(OJPEGState *sp, uint8_t *byte); +static int OJPEGReadBytePeek(OJPEGState *sp, uint8_t *byte); +static void OJPEGReadByteAdvance(OJPEGState *sp); +static int OJPEGReadWord(OJPEGState *sp, uint16_t *word); +static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem); +static void OJPEGReadSkip(OJPEGState *sp, uint16_t len); + +static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len); +static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len); +static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len); +static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len); +static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamRst(TIFF *tif, void **mem, uint32_t *len); +static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len); #ifdef LIBJPEG_ENCAP_EXTERNAL -extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); -extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8_t require_image); -extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); -extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32_t max_lines); -extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32_t max_lines); -extern void jpeg_encap_unwind(TIFF* tif); +extern int jpeg_create_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo); +extern int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, + uint8_t require_image); +extern int jpeg_start_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo); +extern int jpeg_read_scanlines_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, + void *scanlines, uint32_t max_lines); +extern int jpeg_read_raw_data_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, void *data, + uint32_t max_lines); +extern void jpeg_encap_unwind(TIFF *tif); #else -static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j); -static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8_t require_image); -static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo); -static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32_t max_lines); -static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32_t max_lines); -static void jpeg_encap_unwind(TIFF* tif); +static int jpeg_create_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *j); +static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, + uint8_t require_image); +static int jpeg_start_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo); +static int jpeg_read_scanlines_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, + void *scanlines, uint32_t max_lines); +static int jpeg_read_raw_data_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, void *data, + uint32_t max_lines); +static void jpeg_encap_unwind(TIFF *tif); #endif -static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo); -static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo); -static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo); -static boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo); -static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes); -static boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired); -static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo); - -int -TIFFInitOJPEG(TIFF* tif, int scheme) -{ - static const char module[]="TIFFInitOJPEG"; - OJPEGState* sp; - - (void)scheme; - assert(scheme==COMPRESSION_OJPEG); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) { - TIFFErrorExtR(tif, module, - "Merging Old JPEG codec-specific tags failed"); - return 0; - } - - /* state block */ - sp=_TIFFmallocExt(tif, sizeof(OJPEGState)); - if (sp==NULL) - { - TIFFErrorExtR(tif,module,"No space for OJPEG state block"); - return(0); - } - _TIFFmemset(sp,0,sizeof(OJPEGState)); - sp->tif=tif; - sp->jpeg_proc=1; - sp->subsampling_hor=2; - sp->subsampling_ver=2; - TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2); - /* tif codec methods */ - tif->tif_fixuptags=OJPEGFixupTags; - tif->tif_setupdecode=OJPEGSetupDecode; - tif->tif_predecode=OJPEGPreDecode; - tif->tif_postdecode=OJPEGPostDecode; - tif->tif_decoderow=OJPEGDecode; - tif->tif_decodestrip=OJPEGDecode; - tif->tif_decodetile=OJPEGDecode; - tif->tif_setupencode=OJPEGSetupEncode; - tif->tif_preencode=OJPEGPreEncode; - tif->tif_postencode=OJPEGPostEncode; - tif->tif_encoderow=OJPEGEncode; - tif->tif_encodestrip=OJPEGEncode; - tif->tif_encodetile=OJPEGEncode; - tif->tif_cleanup=OJPEGCleanup; - tif->tif_data=(uint8_t*)sp; - /* tif tag methods */ - sp->vgetparent=tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield=OJPEGVGetField; - sp->vsetparent=tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield=OJPEGVSetField; - sp->printdir=tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir=OJPEGPrintDir; - /* Some OJPEG files don't have strip or tile offsets or bytecounts tags. - Some others do, but have totally meaningless or corrupt values - in these tags. In these cases, the JpegInterchangeFormat stream is - reliable. In any case, this decoder reads the compressed data itself, - from the most reliable locations, and we need to notify encapsulating - LibTiff not to read raw strips or tiles for us. */ - tif->tif_flags|=TIFF_NOREADRAW; - return(1); -} +static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo); +static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo); +static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo); +static boolean +OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo); +static void +OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo, + long num_bytes); +static boolean +OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo, + int desired); +static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo); -static int -OJPEGVGetField(TIFF* tif, uint32_t tag, va_list ap) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - switch(tag) - { - case TIFFTAG_JPEGIFOFFSET: - *va_arg(ap, uint64_t*)=(uint64_t)sp->jpeg_interchange_format; - break; - case TIFFTAG_JPEGIFBYTECOUNT: - *va_arg(ap, uint64_t*)=(uint64_t)sp->jpeg_interchange_format_length; - break; - case TIFFTAG_YCBCRSUBSAMPLING: - if (sp->subsamplingcorrect_done==0) - OJPEGSubsamplingCorrect(tif); - *va_arg(ap, uint16_t*)=(uint16_t)sp->subsampling_hor; - *va_arg(ap, uint16_t*)=(uint16_t)sp->subsampling_ver; - break; - case TIFFTAG_JPEGQTABLES: - *va_arg(ap, uint32_t*)=(uint32_t)sp->qtable_offset_count; - *va_arg(ap,const void**)=(const void*)sp->qtable_offset; - break; - case TIFFTAG_JPEGDCTABLES: - *va_arg(ap, uint32_t*)=(uint32_t)sp->dctable_offset_count; - *va_arg(ap,const void**)=(const void*)sp->dctable_offset; - break; - case TIFFTAG_JPEGACTABLES: - *va_arg(ap, uint32_t*)=(uint32_t)sp->actable_offset_count; - *va_arg(ap,const void**)=(const void*)sp->actable_offset; - break; - case TIFFTAG_JPEGPROC: - *va_arg(ap, uint16_t*)=(uint16_t)sp->jpeg_proc; - break; - case TIFFTAG_JPEGRESTARTINTERVAL: - *va_arg(ap, uint16_t*)=sp->restart_interval; - break; - default: - return (*sp->vgetparent)(tif,tag,ap); - } - return (1); +int TIFFInitOJPEG(TIFF *tif, int scheme) +{ + static const char module[] = "TIFFInitOJPEG"; + OJPEGState *sp; + + (void)scheme; + assert(scheme == COMPRESSION_OJPEG); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) + { + TIFFErrorExtR(tif, module, + "Merging Old JPEG codec-specific tags failed"); + return 0; + } + + /* state block */ + sp = _TIFFmallocExt(tif, sizeof(OJPEGState)); + if (sp == NULL) + { + TIFFErrorExtR(tif, module, "No space for OJPEG state block"); + return (0); + } + _TIFFmemset(sp, 0, sizeof(OJPEGState)); + sp->tif = tif; + sp->jpeg_proc = 1; + sp->subsampling_hor = 2; + sp->subsampling_ver = 2; + TIFFSetField(tif, TIFFTAG_YCBCRSUBSAMPLING, 2, 2); + /* tif codec methods */ + tif->tif_fixuptags = OJPEGFixupTags; + tif->tif_setupdecode = OJPEGSetupDecode; + tif->tif_predecode = OJPEGPreDecode; + tif->tif_postdecode = OJPEGPostDecode; + tif->tif_decoderow = OJPEGDecode; + tif->tif_decodestrip = OJPEGDecode; + tif->tif_decodetile = OJPEGDecode; + tif->tif_setupencode = OJPEGSetupEncode; + tif->tif_preencode = OJPEGPreEncode; + tif->tif_postencode = OJPEGPostEncode; + tif->tif_encoderow = OJPEGEncode; + tif->tif_encodestrip = OJPEGEncode; + tif->tif_encodetile = OJPEGEncode; + tif->tif_cleanup = OJPEGCleanup; + tif->tif_data = (uint8_t *)sp; + /* tif tag methods */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = OJPEGVGetField; + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = OJPEGVSetField; + sp->printdir = tif->tif_tagmethods.printdir; + tif->tif_tagmethods.printdir = OJPEGPrintDir; + /* Some OJPEG files don't have strip or tile offsets or bytecounts tags. + Some others do, but have totally meaningless or corrupt values + in these tags. In these cases, the JpegInterchangeFormat stream is + reliable. In any case, this decoder reads the compressed data itself, + from the most reliable locations, and we need to notify encapsulating + LibTiff not to read raw strips or tiles for us. */ + tif->tif_flags |= TIFF_NOREADRAW; + return (1); } -static int -OJPEGVSetField(TIFF* tif, uint32_t tag, va_list ap) -{ - static const char module[]="OJPEGVSetField"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint32_t ma; - uint64_t* mb; - uint32_t n; - const TIFFField* fip; - - switch(tag) - { - case TIFFTAG_JPEGIFOFFSET: - sp->jpeg_interchange_format=(uint64_t)va_arg(ap, uint64_t); - break; - case TIFFTAG_JPEGIFBYTECOUNT: - sp->jpeg_interchange_format_length=(uint64_t)va_arg(ap, uint64_t); - break; - case TIFFTAG_YCBCRSUBSAMPLING: - sp->subsampling_tag=1; - sp->subsampling_hor=(uint8_t)va_arg(ap, uint16_vap); - sp->subsampling_ver=(uint8_t)va_arg(ap, uint16_vap); - tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor; - tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver; - break; - case TIFFTAG_JPEGQTABLES: - ma=(uint32_t)va_arg(ap, uint32_t); - if (ma!=0) - { - if (ma>3) - { - TIFFErrorExtR(tif,module,"JpegQTables tag has incorrect count"); - return(0); - } - sp->qtable_offset_count=(uint8_t)ma; - mb=(uint64_t*)va_arg(ap, uint64_t*); - for (n=0; n<ma; n++) - sp->qtable_offset[n]=mb[n]; - } - break; - case TIFFTAG_JPEGDCTABLES: - ma=(uint32_t)va_arg(ap, uint32_t); - if (ma!=0) - { - if (ma>3) - { - TIFFErrorExtR(tif,module,"JpegDcTables tag has incorrect count"); - return(0); - } - sp->dctable_offset_count=(uint8_t)ma; - mb=(uint64_t*)va_arg(ap, uint64_t*); - for (n=0; n<ma; n++) - sp->dctable_offset[n]=mb[n]; - } - break; - case TIFFTAG_JPEGACTABLES: - ma=(uint32_t)va_arg(ap, uint32_t); - if (ma!=0) - { - if (ma>3) - { - TIFFErrorExtR(tif,module,"JpegAcTables tag has incorrect count"); - return(0); - } - sp->actable_offset_count=(uint8_t)ma; - mb=(uint64_t*)va_arg(ap, uint64_t*); - for (n=0; n<ma; n++) - sp->actable_offset[n]=mb[n]; - } - break; - case TIFFTAG_JPEGPROC: - sp->jpeg_proc=(uint8_t)va_arg(ap, uint16_vap); - break; - case TIFFTAG_JPEGRESTARTINTERVAL: - sp->restart_interval=(uint16_t)va_arg(ap, uint16_vap); - break; - default: - return (*sp->vsetparent)(tif,tag,ap); - } - fip = TIFFFieldWithTag(tif,tag); - if( fip == NULL ) /* shouldn't happen */ - return(0); - TIFFSetFieldBit(tif,fip->field_bit); - tif->tif_flags|=TIFF_DIRTYDIRECT; - return(1); +static int OJPEGVGetField(TIFF *tif, uint32_t tag, va_list ap) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + switch (tag) + { + case TIFFTAG_JPEGIFOFFSET: + *va_arg(ap, uint64_t *) = (uint64_t)sp->jpeg_interchange_format; + break; + case TIFFTAG_JPEGIFBYTECOUNT: + *va_arg(ap, uint64_t *) = + (uint64_t)sp->jpeg_interchange_format_length; + break; + case TIFFTAG_YCBCRSUBSAMPLING: + if (sp->subsamplingcorrect_done == 0) + OJPEGSubsamplingCorrect(tif); + *va_arg(ap, uint16_t *) = (uint16_t)sp->subsampling_hor; + *va_arg(ap, uint16_t *) = (uint16_t)sp->subsampling_ver; + break; + case TIFFTAG_JPEGQTABLES: + *va_arg(ap, uint32_t *) = (uint32_t)sp->qtable_offset_count; + *va_arg(ap, const void **) = (const void *)sp->qtable_offset; + break; + case TIFFTAG_JPEGDCTABLES: + *va_arg(ap, uint32_t *) = (uint32_t)sp->dctable_offset_count; + *va_arg(ap, const void **) = (const void *)sp->dctable_offset; + break; + case TIFFTAG_JPEGACTABLES: + *va_arg(ap, uint32_t *) = (uint32_t)sp->actable_offset_count; + *va_arg(ap, const void **) = (const void *)sp->actable_offset; + break; + case TIFFTAG_JPEGPROC: + *va_arg(ap, uint16_t *) = (uint16_t)sp->jpeg_proc; + break; + case TIFFTAG_JPEGRESTARTINTERVAL: + *va_arg(ap, uint16_t *) = sp->restart_interval; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); } -static void -OJPEGPrintDir(TIFF* tif, FILE* fd, long flags) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t m; - (void)flags; - assert(sp!=NULL); - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT)) - fprintf(fd," JpegInterchangeFormat: %" PRIu64 "\n",(uint64_t)sp->jpeg_interchange_format); - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH)) - fprintf(fd," JpegInterchangeFormatLength: %" PRIu64 "\n",(uint64_t)sp->jpeg_interchange_format_length); - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES)) - { - fprintf(fd," JpegQTables:"); - for (m=0; m<sp->qtable_offset_count; m++) - fprintf(fd," %" PRIu64,(uint64_t)sp->qtable_offset[m]); - fprintf(fd,"\n"); - } - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES)) - { - fprintf(fd," JpegDcTables:"); - for (m=0; m<sp->dctable_offset_count; m++) - fprintf(fd," %" PRIu64,(uint64_t)sp->dctable_offset[m]); - fprintf(fd,"\n"); - } - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES)) - { - fprintf(fd," JpegAcTables:"); - for (m=0; m<sp->actable_offset_count; m++) - fprintf(fd," %" PRIu64,(uint64_t)sp->actable_offset[m]); - fprintf(fd,"\n"); - } - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC)) - fprintf(fd," JpegProc: %"PRIu8"\n", sp->jpeg_proc); - if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL)) - fprintf(fd," JpegRestartInterval: %"PRIu16"\n", sp->restart_interval); - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); +static int OJPEGVSetField(TIFF *tif, uint32_t tag, va_list ap) +{ + static const char module[] = "OJPEGVSetField"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint32_t ma; + uint64_t *mb; + uint32_t n; + const TIFFField *fip; + + switch (tag) + { + case TIFFTAG_JPEGIFOFFSET: + sp->jpeg_interchange_format = (uint64_t)va_arg(ap, uint64_t); + break; + case TIFFTAG_JPEGIFBYTECOUNT: + sp->jpeg_interchange_format_length = (uint64_t)va_arg(ap, uint64_t); + break; + case TIFFTAG_YCBCRSUBSAMPLING: + sp->subsampling_tag = 1; + sp->subsampling_hor = (uint8_t)va_arg(ap, uint16_vap); + sp->subsampling_ver = (uint8_t)va_arg(ap, uint16_vap); + tif->tif_dir.td_ycbcrsubsampling[0] = sp->subsampling_hor; + tif->tif_dir.td_ycbcrsubsampling[1] = sp->subsampling_ver; + break; + case TIFFTAG_JPEGQTABLES: + ma = (uint32_t)va_arg(ap, uint32_t); + if (ma != 0) + { + if (ma > 3) + { + TIFFErrorExtR(tif, module, + "JpegQTables tag has incorrect count"); + return (0); + } + sp->qtable_offset_count = (uint8_t)ma; + mb = (uint64_t *)va_arg(ap, uint64_t *); + for (n = 0; n < ma; n++) + sp->qtable_offset[n] = mb[n]; + } + break; + case TIFFTAG_JPEGDCTABLES: + ma = (uint32_t)va_arg(ap, uint32_t); + if (ma != 0) + { + if (ma > 3) + { + TIFFErrorExtR(tif, module, + "JpegDcTables tag has incorrect count"); + return (0); + } + sp->dctable_offset_count = (uint8_t)ma; + mb = (uint64_t *)va_arg(ap, uint64_t *); + for (n = 0; n < ma; n++) + sp->dctable_offset[n] = mb[n]; + } + break; + case TIFFTAG_JPEGACTABLES: + ma = (uint32_t)va_arg(ap, uint32_t); + if (ma != 0) + { + if (ma > 3) + { + TIFFErrorExtR(tif, module, + "JpegAcTables tag has incorrect count"); + return (0); + } + sp->actable_offset_count = (uint8_t)ma; + mb = (uint64_t *)va_arg(ap, uint64_t *); + for (n = 0; n < ma; n++) + sp->actable_offset[n] = mb[n]; + } + break; + case TIFFTAG_JPEGPROC: + sp->jpeg_proc = (uint8_t)va_arg(ap, uint16_vap); + break; + case TIFFTAG_JPEGRESTARTINTERVAL: + sp->restart_interval = (uint16_t)va_arg(ap, uint16_vap); + break; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + fip = TIFFFieldWithTag(tif, tag); + if (fip == NULL) /* shouldn't happen */ + return (0); + TIFFSetFieldBit(tif, fip->field_bit); + tif->tif_flags |= TIFF_DIRTYDIRECT; + return (1); } -static int -OJPEGFixupTags(TIFF* tif) +static void OJPEGPrintDir(TIFF *tif, FILE *fd, long flags) { - (void) tif; - return(1); + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + (void)flags; + assert(sp != NULL); + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGINTERCHANGEFORMAT)) + fprintf(fd, " JpegInterchangeFormat: %" PRIu64 "\n", + (uint64_t)sp->jpeg_interchange_format); + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH)) + fprintf(fd, " JpegInterchangeFormatLength: %" PRIu64 "\n", + (uint64_t)sp->jpeg_interchange_format_length); + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGQTABLES)) + { + fprintf(fd, " JpegQTables:"); + for (m = 0; m < sp->qtable_offset_count; m++) + fprintf(fd, " %" PRIu64, (uint64_t)sp->qtable_offset[m]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGDCTABLES)) + { + fprintf(fd, " JpegDcTables:"); + for (m = 0; m < sp->dctable_offset_count; m++) + fprintf(fd, " %" PRIu64, (uint64_t)sp->dctable_offset[m]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGACTABLES)) + { + fprintf(fd, " JpegAcTables:"); + for (m = 0; m < sp->actable_offset_count; m++) + fprintf(fd, " %" PRIu64, (uint64_t)sp->actable_offset[m]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGPROC)) + fprintf(fd, " JpegProc: %" PRIu8 "\n", sp->jpeg_proc); + if (TIFFFieldSet(tif, FIELD_OJPEG_JPEGRESTARTINTERVAL)) + fprintf(fd, " JpegRestartInterval: %" PRIu16 "\n", + sp->restart_interval); + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); } -static int -OJPEGSetupDecode(TIFF* tif) +static int OJPEGFixupTags(TIFF *tif) { - static const char module[]="OJPEGSetupDecode"; - TIFFWarningExtR(tif,module,"Deprecated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software"); - return(1); + (void)tif; + return (1); } -static int -OJPEGPreDecode(TIFF* tif, uint16_t s) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint32_t m; - if (sp->subsamplingcorrect_done==0) - OJPEGSubsamplingCorrect(tif); - if (sp->readheader_done==0) - { - if (OJPEGReadHeaderInfo(tif)==0) - return(0); - } - if (sp->sos_end[s].log==0) - { - if (OJPEGReadSecondarySos(tif,s)==0) - return(0); - } - if (isTiled(tif)) - m=tif->tif_curtile; - else - m=tif->tif_curstrip; - if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m))) - { - if (sp->libjpeg_session_active!=0) - OJPEGLibjpegSessionAbort(tif); - sp->writeheader_done=0; - } - if (sp->writeheader_done==0) - { - sp->plane_sample_offset=(uint8_t)s; - sp->write_cursample=s; - sp->write_curstrile=s*tif->tif_dir.td_stripsperimage; - if ((sp->in_buffer_file_pos_log==0) || - (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos)) - { - sp->in_buffer_source=sp->sos_end[s].in_buffer_source; - sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile; - sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos; - sp->in_buffer_file_pos_log=0; - sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo; - sp->in_buffer_togo=0; - sp->in_buffer_cur=0; - } - if (OJPEGWriteHeaderInfo(tif)==0) - return(0); - } - while (sp->write_curstrile<m) - { - if (sp->libjpeg_jpeg_query_style==0) - { - if (OJPEGPreDecodeSkipRaw(tif)==0) - return(0); - } - else - { - if (OJPEGPreDecodeSkipScanlines(tif)==0) - return(0); - } - sp->write_curstrile++; - } - sp->decoder_ok = 1; - return(1); +static int OJPEGSetupDecode(TIFF *tif) +{ + static const char module[] = "OJPEGSetupDecode"; + TIFFWarningExtR(tif, module, + "Deprecated and troublesome old-style JPEG compression " + "mode, please convert to new-style JPEG compression and " + "notify vendor of writing software"); + return (1); } -static int -OJPEGPreDecodeSkipRaw(TIFF* tif) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint32_t m; - m=sp->lines_per_strile; - if (sp->subsampling_convert_state!=0) - { - if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m) - { - sp->subsampling_convert_state+=m; - if (sp->subsampling_convert_state==sp->subsampling_convert_clines) - sp->subsampling_convert_state=0; - return(1); - } - m-=sp->subsampling_convert_clines-sp->subsampling_convert_state; - sp->subsampling_convert_state=0; - sp->error_in_raw_data_decoding=0; - } - while (m>=sp->subsampling_convert_clines) - { - if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) - return(0); - m-=sp->subsampling_convert_clines; - } - if (m>0) - { - if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) - return(0); - sp->subsampling_convert_state=m; - } - return(1); +static int OJPEGPreDecode(TIFF *tif, uint16_t s) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint32_t m; + if (sp->subsamplingcorrect_done == 0) + OJPEGSubsamplingCorrect(tif); + if (sp->readheader_done == 0) + { + if (OJPEGReadHeaderInfo(tif) == 0) + return (0); + } + if (sp->sos_end[s].log == 0) + { + if (OJPEGReadSecondarySos(tif, s) == 0) + return (0); + } + if (isTiled(tif)) + m = tif->tif_curtile; + else + m = tif->tif_curstrip; + if ((sp->writeheader_done != 0) && + ((sp->write_cursample != s) || (sp->write_curstrile > m))) + { + if (sp->libjpeg_session_active != 0) + OJPEGLibjpegSessionAbort(tif); + sp->writeheader_done = 0; + } + if (sp->writeheader_done == 0) + { + sp->plane_sample_offset = (uint8_t)s; + sp->write_cursample = s; + sp->write_curstrile = s * tif->tif_dir.td_stripsperimage; + if ((sp->in_buffer_file_pos_log == 0) || + (sp->in_buffer_file_pos - sp->in_buffer_togo != + sp->sos_end[s].in_buffer_file_pos)) + { + sp->in_buffer_source = sp->sos_end[s].in_buffer_source; + sp->in_buffer_next_strile = sp->sos_end[s].in_buffer_next_strile; + sp->in_buffer_file_pos = sp->sos_end[s].in_buffer_file_pos; + sp->in_buffer_file_pos_log = 0; + sp->in_buffer_file_togo = sp->sos_end[s].in_buffer_file_togo; + sp->in_buffer_togo = 0; + sp->in_buffer_cur = 0; + } + if (OJPEGWriteHeaderInfo(tif) == 0) + return (0); + } + while (sp->write_curstrile < m) + { + if (sp->libjpeg_jpeg_query_style == 0) + { + if (OJPEGPreDecodeSkipRaw(tif) == 0) + return (0); + } + else + { + if (OJPEGPreDecodeSkipScanlines(tif) == 0) + return (0); + } + sp->write_curstrile++; + } + sp->decoder_ok = 1; + return (1); } -static int -OJPEGPreDecodeSkipScanlines(TIFF* tif) -{ - static const char module[]="OJPEGPreDecodeSkipScanlines"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint32_t m; - if (sp->skip_buffer==NULL) - { - sp->skip_buffer=_TIFFmallocExt(tif, sp->bytes_per_line); - if (sp->skip_buffer==NULL) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - } - for (m=0; m<sp->lines_per_strile; m++) - { - if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0) - return(0); - } - return(1); +static int OJPEGPreDecodeSkipRaw(TIFF *tif) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint32_t m; + m = sp->lines_per_strile; + if (sp->subsampling_convert_state != 0) + { + if (sp->subsampling_convert_clines - sp->subsampling_convert_state >= m) + { + sp->subsampling_convert_state += m; + if (sp->subsampling_convert_state == sp->subsampling_convert_clines) + sp->subsampling_convert_state = 0; + return (1); + } + m -= sp->subsampling_convert_clines - sp->subsampling_convert_state; + sp->subsampling_convert_state = 0; + sp->error_in_raw_data_decoding = 0; + } + while (m >= sp->subsampling_convert_clines) + { + if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), + sp->subsampling_convert_ycbcrimage, + sp->subsampling_ver * 8) == 0) + return (0); + m -= sp->subsampling_convert_clines; + } + if (m > 0) + { + if (jpeg_read_raw_data_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), + sp->subsampling_convert_ycbcrimage, + sp->subsampling_ver * 8) == 0) + return (0); + sp->subsampling_convert_state = m; + } + return (1); } -static int -OJPEGDecode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) +static int OJPEGPreDecodeSkipScanlines(TIFF *tif) { - static const char module[]="OJPEGDecode"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - (void)s; - if( !sp->decoder_ok ) + static const char module[] = "OJPEGPreDecodeSkipScanlines"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint32_t m; + if (sp->skip_buffer == NULL) + { + sp->skip_buffer = _TIFFmallocExt(tif, sp->bytes_per_line); + if (sp->skip_buffer == NULL) { - TIFFErrorExtR(tif,module,"Cannot decode: decoder not correctly initialized"); - return 0; + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); } - if( sp->libjpeg_session_active == 0 ) + } + for (m = 0; m < sp->lines_per_strile; m++) + { + if (jpeg_read_scanlines_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), + &sp->skip_buffer, 1) == 0) + return (0); + } + return (1); +} + +static int OJPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) +{ + static const char module[] = "OJPEGDecode"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + (void)s; + if (!sp->decoder_ok) + { + TIFFErrorExtR(tif, module, + "Cannot decode: decoder not correctly initialized"); + return 0; + } + if (sp->libjpeg_session_active == 0) + { + /* This should normally not happen, except that it does when */ + /* using TIFFReadScanline() which calls OJPEGPostDecode() for */ + /* each scanline, which assumes that a whole strile was read */ + /* and may thus incorrectly consider it has read the whole image, + * causing */ + /* OJPEGLibjpegSessionAbort() to be called prematurely. */ + /* Triggered by https://gitlab.com/libtiff/libtiff/-/issues/337 */ + TIFFErrorExtR(tif, module, + "Cannot decode: libjpeg_session_active == 0"); + return 0; + } + if (sp->error_in_raw_data_decoding) + { + return 0; + } + if (sp->libjpeg_jpeg_query_style == 0) + { + if (OJPEGDecodeRaw(tif, buf, cc) == 0) + return (0); + } + else + { + if (OJPEGDecodeScanlines(tif, buf, cc) == 0) + return (0); + } + return (1); +} + +static int OJPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc) +{ + static const char module[] = "OJPEGDecodeRaw"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t *m; + tmsize_t n; + uint8_t *oy; + uint8_t *ocb; + uint8_t *ocr; + uint8_t *p; + uint32_t q; + uint8_t *r; + uint8_t sx, sy; + if (cc % sp->bytes_per_line != 0) + { + TIFFErrorExtR(tif, module, "Fractional scanline not read"); + return (0); + } + assert(cc > 0); + m = buf; + n = cc; + do + { + if (sp->subsampling_convert_state == 0) { - /* This should normally not happen, except that it does when */ - /* using TIFFReadScanline() which calls OJPEGPostDecode() for */ - /* each scanline, which assumes that a whole strile was read */ - /* and may thus incorrectly consider it has read the whole image, causing */ - /* OJPEGLibjpegSessionAbort() to be called prematurely. */ - /* Triggered by https://gitlab.com/libtiff/libtiff/-/issues/337 */ - TIFFErrorExtR(tif,module,"Cannot decode: libjpeg_session_active == 0"); - return 0; + if (jpeg_read_raw_data_encap(sp, + &(sp->libjpeg_jpeg_decompress_struct), + sp->subsampling_convert_ycbcrimage, + sp->subsampling_ver * 8) == 0) + { + sp->error_in_raw_data_decoding = 1; + return (0); + } } - if( sp->error_in_raw_data_decoding ) + oy = sp->subsampling_convert_ybuf + + sp->subsampling_convert_state * sp->subsampling_ver * + sp->subsampling_convert_ylinelen; + ocb = sp->subsampling_convert_cbbuf + + sp->subsampling_convert_state * sp->subsampling_convert_clinelen; + ocr = sp->subsampling_convert_crbuf + + sp->subsampling_convert_state * sp->subsampling_convert_clinelen; + p = m; + for (q = 0; q < sp->subsampling_convert_clinelenout; q++) { - return 0; + r = oy; + for (sy = 0; sy < sp->subsampling_ver; sy++) + { + for (sx = 0; sx < sp->subsampling_hor; sx++) + *p++ = *r++; + r += sp->subsampling_convert_ylinelen - sp->subsampling_hor; + } + oy += sp->subsampling_hor; + *p++ = *ocb++; + *p++ = *ocr++; } - if (sp->libjpeg_jpeg_query_style==0) - { - if (OJPEGDecodeRaw(tif,buf,cc)==0) - return(0); - } - else - { - if (OJPEGDecodeScanlines(tif,buf,cc)==0) - return(0); - } - return(1); -} - -static int -OJPEGDecodeRaw(TIFF* tif, uint8_t* buf, tmsize_t cc) -{ - static const char module[]="OJPEGDecodeRaw"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t* m; - tmsize_t n; - uint8_t* oy; - uint8_t* ocb; - uint8_t* ocr; - uint8_t* p; - uint32_t q; - uint8_t* r; - uint8_t sx,sy; - if (cc%sp->bytes_per_line!=0) - { - TIFFErrorExtR(tif,module,"Fractional scanline not read"); - return(0); - } - assert(cc>0); - m=buf; - n=cc; - do - { - if (sp->subsampling_convert_state==0) - { - if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0) - { - sp->error_in_raw_data_decoding = 1; - return(0); - } - } - oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen; - ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen; - ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen; - p=m; - for (q=0; q<sp->subsampling_convert_clinelenout; q++) - { - r=oy; - for (sy=0; sy<sp->subsampling_ver; sy++) - { - for (sx=0; sx<sp->subsampling_hor; sx++) - *p++=*r++; - r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor; - } - oy+=sp->subsampling_hor; - *p++=*ocb++; - *p++=*ocr++; - } - sp->subsampling_convert_state++; - if (sp->subsampling_convert_state==sp->subsampling_convert_clines) - sp->subsampling_convert_state=0; - m+=sp->bytes_per_line; - n-=sp->bytes_per_line; - } while(n>0); - return(1); + sp->subsampling_convert_state++; + if (sp->subsampling_convert_state == sp->subsampling_convert_clines) + sp->subsampling_convert_state = 0; + m += sp->bytes_per_line; + n -= sp->bytes_per_line; + } while (n > 0); + return (1); } -static int -OJPEGDecodeScanlines(TIFF* tif, uint8_t* buf, tmsize_t cc) -{ - static const char module[]="OJPEGDecodeScanlines"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t* m; - tmsize_t n; - if (cc%sp->bytes_per_line!=0) - { - TIFFErrorExtR(tif,module,"Fractional scanline not read"); - return(0); - } - assert(cc>0); - m=buf; - n=cc; - do - { - if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0) - return(0); - m+=sp->bytes_per_line; - n-=sp->bytes_per_line; - } while(n>0); - return(1); +static int OJPEGDecodeScanlines(TIFF *tif, uint8_t *buf, tmsize_t cc) +{ + static const char module[] = "OJPEGDecodeScanlines"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t *m; + tmsize_t n; + if (cc % sp->bytes_per_line != 0) + { + TIFFErrorExtR(tif, module, "Fractional scanline not read"); + return (0); + } + assert(cc > 0); + m = buf; + n = cc; + do + { + if (jpeg_read_scanlines_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), + &m, 1) == 0) + return (0); + m += sp->bytes_per_line; + n -= sp->bytes_per_line; + } while (n > 0); + return (1); } -static void -OJPEGPostDecode(TIFF* tif, uint8_t* buf, tmsize_t cc) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - (void)buf; - (void)cc; - /* This function somehow incorrectly assumes that a whole strile was read, */ - /* which is not true when TIFFReadScanline() is called, */ - /* and may thus incorrectly consider it has read the whole image, causing */ - /* OJPEGLibjpegSessionAbort() to be called prematurely. */ - /* So this logic should be fixed to take into account cc, or disable */ - /* the scan line reading interface. */ - /* Triggered by https://gitlab.com/libtiff/libtiff/-/issues/337 */ - sp->write_curstrile++; - if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0) - { - assert(sp->libjpeg_session_active!=0); - OJPEGLibjpegSessionAbort(tif); - sp->writeheader_done=0; - } +static void OJPEGPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + (void)buf; + (void)cc; + /* This function somehow incorrectly assumes that a whole strile was read, + */ + /* which is not true when TIFFReadScanline() is called, */ + /* and may thus incorrectly consider it has read the whole image, causing */ + /* OJPEGLibjpegSessionAbort() to be called prematurely. */ + /* So this logic should be fixed to take into account cc, or disable */ + /* the scan line reading interface. */ + /* Triggered by https://gitlab.com/libtiff/libtiff/-/issues/337 */ + sp->write_curstrile++; + if (sp->write_curstrile % tif->tif_dir.td_stripsperimage == 0) + { + assert(sp->libjpeg_session_active != 0); + OJPEGLibjpegSessionAbort(tif); + sp->writeheader_done = 0; + } } -static int -OJPEGSetupEncode(TIFF* tif) +static int OJPEGSetupEncode(TIFF *tif) { - static const char module[]="OJPEGSetupEncode"; - TIFFErrorExtR(tif,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); - return(0); + static const char module[] = "OJPEGSetupEncode"; + TIFFErrorExtR( + tif, module, + "OJPEG encoding not supported; use new-style JPEG compression instead"); + return (0); } -static int -OJPEGPreEncode(TIFF* tif, uint16_t s) +static int OJPEGPreEncode(TIFF *tif, uint16_t s) { - static const char module[]="OJPEGPreEncode"; - (void)s; - TIFFErrorExtR(tif,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); - return(0); + static const char module[] = "OJPEGPreEncode"; + (void)s; + TIFFErrorExtR( + tif, module, + "OJPEG encoding not supported; use new-style JPEG compression instead"); + return (0); } -static int -OJPEGEncode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) +static int OJPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - static const char module[]="OJPEGEncode"; - (void)buf; - (void)cc; - (void)s; - TIFFErrorExtR(tif,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); - return(0); + static const char module[] = "OJPEGEncode"; + (void)buf; + (void)cc; + (void)s; + TIFFErrorExtR( + tif, module, + "OJPEG encoding not supported; use new-style JPEG compression instead"); + return (0); } -static int -OJPEGPostEncode(TIFF* tif) +static int OJPEGPostEncode(TIFF *tif) { - static const char module[]="OJPEGPostEncode"; - TIFFErrorExtR(tif,module,"OJPEG encoding not supported; use new-style JPEG compression instead"); - return(0); + static const char module[] = "OJPEGPostEncode"; + TIFFErrorExtR( + tif, module, + "OJPEG encoding not supported; use new-style JPEG compression instead"); + return (0); } -static void -OJPEGCleanup(TIFF* tif) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - if (sp!=0) - { - tif->tif_tagmethods.vgetfield=sp->vgetparent; - tif->tif_tagmethods.vsetfield=sp->vsetparent; - tif->tif_tagmethods.printdir=sp->printdir; - if (sp->qtable[0]!=0) - _TIFFfreeExt(tif, sp->qtable[0]); - if (sp->qtable[1]!=0) - _TIFFfreeExt(tif, sp->qtable[1]); - if (sp->qtable[2]!=0) - _TIFFfreeExt(tif, sp->qtable[2]); - if (sp->qtable[3]!=0) - _TIFFfreeExt(tif, sp->qtable[3]); - if (sp->dctable[0]!=0) - _TIFFfreeExt(tif, sp->dctable[0]); - if (sp->dctable[1]!=0) - _TIFFfreeExt(tif, sp->dctable[1]); - if (sp->dctable[2]!=0) - _TIFFfreeExt(tif, sp->dctable[2]); - if (sp->dctable[3]!=0) - _TIFFfreeExt(tif, sp->dctable[3]); - if (sp->actable[0]!=0) - _TIFFfreeExt(tif, sp->actable[0]); - if (sp->actable[1]!=0) - _TIFFfreeExt(tif, sp->actable[1]); - if (sp->actable[2]!=0) - _TIFFfreeExt(tif, sp->actable[2]); - if (sp->actable[3]!=0) - _TIFFfreeExt(tif, sp->actable[3]); - if (sp->libjpeg_session_active!=0) - OJPEGLibjpegSessionAbort(tif); - if (sp->subsampling_convert_ycbcrbuf!=0) - _TIFFfreeExt(tif, sp->subsampling_convert_ycbcrbuf); - if (sp->subsampling_convert_ycbcrimage!=0) - _TIFFfreeExt(tif, sp->subsampling_convert_ycbcrimage); - if (sp->skip_buffer!=0) - _TIFFfreeExt(tif, sp->skip_buffer); - _TIFFfreeExt(tif, sp); - tif->tif_data=NULL; - _TIFFSetDefaultCompressionState(tif); - } +static void OJPEGCleanup(TIFF *tif) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + if (sp != 0) + { + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.printdir = sp->printdir; + if (sp->qtable[0] != 0) + _TIFFfreeExt(tif, sp->qtable[0]); + if (sp->qtable[1] != 0) + _TIFFfreeExt(tif, sp->qtable[1]); + if (sp->qtable[2] != 0) + _TIFFfreeExt(tif, sp->qtable[2]); + if (sp->qtable[3] != 0) + _TIFFfreeExt(tif, sp->qtable[3]); + if (sp->dctable[0] != 0) + _TIFFfreeExt(tif, sp->dctable[0]); + if (sp->dctable[1] != 0) + _TIFFfreeExt(tif, sp->dctable[1]); + if (sp->dctable[2] != 0) + _TIFFfreeExt(tif, sp->dctable[2]); + if (sp->dctable[3] != 0) + _TIFFfreeExt(tif, sp->dctable[3]); + if (sp->actable[0] != 0) + _TIFFfreeExt(tif, sp->actable[0]); + if (sp->actable[1] != 0) + _TIFFfreeExt(tif, sp->actable[1]); + if (sp->actable[2] != 0) + _TIFFfreeExt(tif, sp->actable[2]); + if (sp->actable[3] != 0) + _TIFFfreeExt(tif, sp->actable[3]); + if (sp->libjpeg_session_active != 0) + OJPEGLibjpegSessionAbort(tif); + if (sp->subsampling_convert_ycbcrbuf != 0) + _TIFFfreeExt(tif, sp->subsampling_convert_ycbcrbuf); + if (sp->subsampling_convert_ycbcrimage != 0) + _TIFFfreeExt(tif, sp->subsampling_convert_ycbcrimage); + if (sp->skip_buffer != 0) + _TIFFfreeExt(tif, sp->skip_buffer); + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; + _TIFFSetDefaultCompressionState(tif); + } } -static void -OJPEGSubsamplingCorrect(TIFF* tif) -{ - static const char module[]="OJPEGSubsamplingCorrect"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t mh; - uint8_t mv; - - assert(sp->subsamplingcorrect_done==0); - if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) && - (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB))) - { - if (sp->subsampling_tag!=0) - TIFFWarningExtR(tif,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel"); - sp->subsampling_hor=1; - sp->subsampling_ver=1; - sp->subsampling_force_desubsampling_inside_decompression=0; - } - else - { - sp->subsamplingcorrect_done=1; - mh=sp->subsampling_hor; - mv=sp->subsampling_ver; - sp->subsamplingcorrect=1; - OJPEGReadHeaderInfoSec(tif); - if (sp->subsampling_force_desubsampling_inside_decompression!=0) - { - sp->subsampling_hor=1; - sp->subsampling_ver=1; - } - sp->subsamplingcorrect=0; - if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0)) - { - if (sp->subsampling_tag==0) - TIFFWarningExtR(tif,module,"Subsampling tag is not set, yet subsampling inside JPEG data [%"PRIu8",%"PRIu8"] does not match default values [2,2]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver); - else - TIFFWarningExtR(tif,module,"Subsampling inside JPEG data [%"PRIu8",%"PRIu8"] does not match subsampling tag values [%"PRIu8",%"PRIu8"]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver,mh,mv); - } - if (sp->subsampling_force_desubsampling_inside_decompression!=0) - { - if (sp->subsampling_tag==0) - TIFFWarningExtR(tif,module,"Subsampling tag is not set, yet subsampling inside JPEG data does not match default values [2,2] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression"); - else - TIFFWarningExtR(tif,module,"Subsampling inside JPEG data does not match subsampling tag values [%"PRIu8",%"PRIu8"] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression",mh,mv); - } - if (sp->subsampling_force_desubsampling_inside_decompression==0) - { - if (sp->subsampling_hor<sp->subsampling_ver) - TIFFWarningExtR(tif,module,"Subsampling values [%"PRIu8",%"PRIu8"] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver); - } - } - sp->subsamplingcorrect_done=1; +static void OJPEGSubsamplingCorrect(TIFF *tif) +{ + static const char module[] = "OJPEGSubsamplingCorrect"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t mh; + uint8_t mv; + + assert(sp->subsamplingcorrect_done == 0); + if ((tif->tif_dir.td_samplesperpixel != 3) || + ((tif->tif_dir.td_photometric != PHOTOMETRIC_YCBCR) && + (tif->tif_dir.td_photometric != PHOTOMETRIC_ITULAB))) + { + if (sp->subsampling_tag != 0) + TIFFWarningExtR(tif, module, + "Subsampling tag not appropriate for this " + "Photometric and/or SamplesPerPixel"); + sp->subsampling_hor = 1; + sp->subsampling_ver = 1; + sp->subsampling_force_desubsampling_inside_decompression = 0; + } + else + { + sp->subsamplingcorrect_done = 1; + mh = sp->subsampling_hor; + mv = sp->subsampling_ver; + sp->subsamplingcorrect = 1; + OJPEGReadHeaderInfoSec(tif); + if (sp->subsampling_force_desubsampling_inside_decompression != 0) + { + sp->subsampling_hor = 1; + sp->subsampling_ver = 1; + } + sp->subsamplingcorrect = 0; + if (((sp->subsampling_hor != mh) || (sp->subsampling_ver != mv)) && + (sp->subsampling_force_desubsampling_inside_decompression == 0)) + { + if (sp->subsampling_tag == 0) + TIFFWarningExtR( + tif, module, + "Subsampling tag is not set, yet subsampling inside JPEG " + "data [%" PRIu8 ",%" PRIu8 + "] does not match default values [2,2]; assuming " + "subsampling inside JPEG data is correct", + sp->subsampling_hor, sp->subsampling_ver); + else + TIFFWarningExtR( + tif, module, + "Subsampling inside JPEG data [%" PRIu8 ",%" PRIu8 + "] does not match subsampling tag values [%" PRIu8 + ",%" PRIu8 + "]; assuming subsampling inside JPEG data is correct", + sp->subsampling_hor, sp->subsampling_ver, mh, mv); + } + if (sp->subsampling_force_desubsampling_inside_decompression != 0) + { + if (sp->subsampling_tag == 0) + TIFFWarningExtR( + tif, module, + "Subsampling tag is not set, yet subsampling inside JPEG " + "data does not match default values [2,2] (nor any other " + "values allowed in TIFF); assuming subsampling inside JPEG " + "data is correct and desubsampling inside JPEG " + "decompression"); + else + TIFFWarningExtR( + tif, module, + "Subsampling inside JPEG data does not match subsampling " + "tag values [%" PRIu8 ",%" PRIu8 + "] (nor any other values allowed in TIFF); assuming " + "subsampling inside JPEG data is correct and desubsampling " + "inside JPEG decompression", + mh, mv); + } + if (sp->subsampling_force_desubsampling_inside_decompression == 0) + { + if (sp->subsampling_hor < sp->subsampling_ver) + TIFFWarningExtR(tif, module, + "Subsampling values [%" PRIu8 ",%" PRIu8 + "] are not allowed in TIFF", + sp->subsampling_hor, sp->subsampling_ver); + } + } + sp->subsamplingcorrect_done = 1; } -static int -OJPEGReadHeaderInfo(TIFF* tif) -{ - static const char module[]="OJPEGReadHeaderInfo"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(sp->readheader_done==0); - sp->image_width=tif->tif_dir.td_imagewidth; - sp->image_length=tif->tif_dir.td_imagelength; - if (isTiled(tif)) - { - sp->strile_width=tif->tif_dir.td_tilewidth; - sp->strile_length=tif->tif_dir.td_tilelength; - sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length; - } - else - { - sp->strile_width=sp->image_width; - sp->strile_length=tif->tif_dir.td_rowsperstrip; - if( sp->strile_length == (uint32_t)-1 ) - sp->strile_length = sp->image_length; - sp->strile_length_total=sp->image_length; - } - if (tif->tif_dir.td_samplesperpixel==1) - { - sp->samples_per_pixel=1; - sp->plane_sample_offset=0; - sp->samples_per_pixel_per_plane=sp->samples_per_pixel; - sp->subsampling_hor=1; - sp->subsampling_ver=1; - } - else - { - if (tif->tif_dir.td_samplesperpixel!=3) - { - TIFFErrorExtR(tif,module,"SamplesPerPixel %"PRIu8" not supported for this compression scheme",sp->samples_per_pixel); - return(0); - } - sp->samples_per_pixel=3; - sp->plane_sample_offset=0; - if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG) - sp->samples_per_pixel_per_plane=3; - else - sp->samples_per_pixel_per_plane=1; - } - if (sp->strile_length<sp->image_length) - { - if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) || - ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4))) - { - TIFFErrorExtR(tif,module,"Invalid subsampling values"); - return(0); - } - if (sp->strile_length%(sp->subsampling_ver*8)!=0) - { - TIFFErrorExtR(tif,module,"Incompatible vertical subsampling and image strip/tile length"); - return(0); - } - sp->restart_interval=(uint16_t)(((sp->strile_width + sp->subsampling_hor * 8 - 1) / (sp->subsampling_hor * 8)) * (sp->strile_length / (sp->subsampling_ver * 8))); - } - if (OJPEGReadHeaderInfoSec(tif)==0) - return(0); - sp->sos_end[0].log=1; - sp->sos_end[0].in_buffer_source=sp->in_buffer_source; - sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile; - sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo; - sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; - sp->readheader_done=1; - return(1); +static int OJPEGReadHeaderInfo(TIFF *tif) +{ + static const char module[] = "OJPEGReadHeaderInfo"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(sp->readheader_done == 0); + sp->image_width = tif->tif_dir.td_imagewidth; + sp->image_length = tif->tif_dir.td_imagelength; + if (isTiled(tif)) + { + sp->strile_width = tif->tif_dir.td_tilewidth; + sp->strile_length = tif->tif_dir.td_tilelength; + sp->strile_length_total = + ((sp->image_length + sp->strile_length - 1) / sp->strile_length) * + sp->strile_length; + } + else + { + sp->strile_width = sp->image_width; + sp->strile_length = tif->tif_dir.td_rowsperstrip; + if (sp->strile_length == (uint32_t)-1) + sp->strile_length = sp->image_length; + sp->strile_length_total = sp->image_length; + } + if (tif->tif_dir.td_samplesperpixel == 1) + { + sp->samples_per_pixel = 1; + sp->plane_sample_offset = 0; + sp->samples_per_pixel_per_plane = sp->samples_per_pixel; + sp->subsampling_hor = 1; + sp->subsampling_ver = 1; + } + else + { + if (tif->tif_dir.td_samplesperpixel != 3) + { + TIFFErrorExtR(tif, module, + "SamplesPerPixel %" PRIu8 + " not supported for this compression scheme", + sp->samples_per_pixel); + return (0); + } + sp->samples_per_pixel = 3; + sp->plane_sample_offset = 0; + if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) + sp->samples_per_pixel_per_plane = 3; + else + sp->samples_per_pixel_per_plane = 1; + } + if (sp->strile_length < sp->image_length) + { + if (((sp->subsampling_hor != 1) && (sp->subsampling_hor != 2) && + (sp->subsampling_hor != 4)) || + ((sp->subsampling_ver != 1) && (sp->subsampling_ver != 2) && + (sp->subsampling_ver != 4))) + { + TIFFErrorExtR(tif, module, "Invalid subsampling values"); + return (0); + } + if (sp->strile_length % (sp->subsampling_ver * 8) != 0) + { + TIFFErrorExtR(tif, module, + "Incompatible vertical subsampling and image " + "strip/tile length"); + return (0); + } + sp->restart_interval = + (uint16_t)(((sp->strile_width + sp->subsampling_hor * 8 - 1) / + (sp->subsampling_hor * 8)) * + (sp->strile_length / (sp->subsampling_ver * 8))); + } + if (OJPEGReadHeaderInfoSec(tif) == 0) + return (0); + sp->sos_end[0].log = 1; + sp->sos_end[0].in_buffer_source = sp->in_buffer_source; + sp->sos_end[0].in_buffer_next_strile = sp->in_buffer_next_strile; + sp->sos_end[0].in_buffer_file_pos = + sp->in_buffer_file_pos - sp->in_buffer_togo; + sp->sos_end[0].in_buffer_file_togo = + sp->in_buffer_file_togo + sp->in_buffer_togo; + sp->readheader_done = 1; + return (1); } -static int -OJPEGReadSecondarySos(TIFF* tif, uint16_t s) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t m; - assert(s>0); - assert(s<3); - assert(sp->sos_end[0].log!=0); - assert(sp->sos_end[s].log==0); - sp->plane_sample_offset=(uint8_t)(s - 1); - while(sp->sos_end[sp->plane_sample_offset].log==0) - sp->plane_sample_offset--; - sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source; - sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile; - sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos; - sp->in_buffer_file_pos_log=0; - sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo; - sp->in_buffer_togo=0; - sp->in_buffer_cur=0; - while(sp->plane_sample_offset<s) - { - do - { - if (OJPEGReadByte(sp,&m)==0) - return(0); - if (m==255) - { - do - { - if (OJPEGReadByte(sp,&m)==0) - return(0); - if (m!=255) - break; - } while(1); - if (m==JPEG_MARKER_SOS) - break; - } - } while(1); - sp->plane_sample_offset++; - if (OJPEGReadHeaderInfoSecStreamSos(tif)==0) - return(0); - sp->sos_end[sp->plane_sample_offset].log=1; - sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source; - sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile; - sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo; - sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; - } - return(1); +static int OJPEGReadSecondarySos(TIFF *tif, uint16_t s) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + assert(s > 0); + assert(s < 3); + assert(sp->sos_end[0].log != 0); + assert(sp->sos_end[s].log == 0); + sp->plane_sample_offset = (uint8_t)(s - 1); + while (sp->sos_end[sp->plane_sample_offset].log == 0) + sp->plane_sample_offset--; + sp->in_buffer_source = + sp->sos_end[sp->plane_sample_offset].in_buffer_source; + sp->in_buffer_next_strile = + sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile; + sp->in_buffer_file_pos = + sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos; + sp->in_buffer_file_pos_log = 0; + sp->in_buffer_file_togo = + sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo; + sp->in_buffer_togo = 0; + sp->in_buffer_cur = 0; + while (sp->plane_sample_offset < s) + { + do + { + if (OJPEGReadByte(sp, &m) == 0) + return (0); + if (m == 255) + { + do + { + if (OJPEGReadByte(sp, &m) == 0) + return (0); + if (m != 255) + break; + } while (1); + if (m == JPEG_MARKER_SOS) + break; + } + } while (1); + sp->plane_sample_offset++; + if (OJPEGReadHeaderInfoSecStreamSos(tif) == 0) + return (0); + sp->sos_end[sp->plane_sample_offset].log = 1; + sp->sos_end[sp->plane_sample_offset].in_buffer_source = + sp->in_buffer_source; + sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile = + sp->in_buffer_next_strile; + sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos = + sp->in_buffer_file_pos - sp->in_buffer_togo; + sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo = + sp->in_buffer_file_togo + sp->in_buffer_togo; + } + return (1); } -static int -OJPEGWriteHeaderInfo(TIFF* tif) -{ - static const char module[]="OJPEGWriteHeaderInfo"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t** m; - uint32_t n; - /* if a previous attempt failed, don't try again */ - if (sp->libjpeg_session_active != 0) - return 0; - sp->out_state=ososSoi; - sp->restart_index=0; - jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr)); - sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage; - sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit; - sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr); - sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif; - if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0) - return(0); - sp->libjpeg_session_active=1; - sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0; - sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource; - sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer; - sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData; - sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart; - sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource; - sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr); - if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0) - return(0); - if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1)) - { - sp->libjpeg_jpeg_decompress_struct.raw_data_out=1; +static int OJPEGWriteHeaderInfo(TIFF *tif) +{ + static const char module[] = "OJPEGWriteHeaderInfo"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t **m; + uint32_t n; + /* if a previous attempt failed, don't try again */ + if (sp->libjpeg_session_active != 0) + return 0; + sp->out_state = ososSoi; + sp->restart_index = 0; + jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr)); + sp->libjpeg_jpeg_error_mgr.output_message = + OJPEGLibjpegJpegErrorMgrOutputMessage; + sp->libjpeg_jpeg_error_mgr.error_exit = OJPEGLibjpegJpegErrorMgrErrorExit; + sp->libjpeg_jpeg_decompress_struct.err = &(sp->libjpeg_jpeg_error_mgr); + sp->libjpeg_jpeg_decompress_struct.client_data = (void *)tif; + if (jpeg_create_decompress_encap( + sp, &(sp->libjpeg_jpeg_decompress_struct)) == 0) + return (0); + sp->libjpeg_session_active = 1; + sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = 0; + sp->libjpeg_jpeg_source_mgr.init_source = + OJPEGLibjpegJpegSourceMgrInitSource; + sp->libjpeg_jpeg_source_mgr.fill_input_buffer = + OJPEGLibjpegJpegSourceMgrFillInputBuffer; + sp->libjpeg_jpeg_source_mgr.skip_input_data = + OJPEGLibjpegJpegSourceMgrSkipInputData; + sp->libjpeg_jpeg_source_mgr.resync_to_restart = + OJPEGLibjpegJpegSourceMgrResyncToRestart; + sp->libjpeg_jpeg_source_mgr.term_source = + OJPEGLibjpegJpegSourceMgrTermSource; + sp->libjpeg_jpeg_decompress_struct.src = &(sp->libjpeg_jpeg_source_mgr); + if (jpeg_read_header_encap(sp, &(sp->libjpeg_jpeg_decompress_struct), 1) == + 0) + return (0); + if ((sp->subsampling_force_desubsampling_inside_decompression == 0) && + (sp->samples_per_pixel_per_plane > 1)) + { + sp->libjpeg_jpeg_decompress_struct.raw_data_out = 1; #if JPEG_LIB_VERSION >= 70 - sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling=FALSE; + sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling = FALSE; #endif - sp->libjpeg_jpeg_query_style=0; - if (sp->subsampling_convert_log==0) - { - assert(sp->subsampling_convert_ycbcrbuf==0); - assert(sp->subsampling_convert_ycbcrimage==0); - sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8); - sp->subsampling_convert_ylines=sp->subsampling_ver*8; - sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor; - sp->subsampling_convert_clines=8; - sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines; - sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines; - sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen; - /* The calloc is not normally necessary, except in some edge/broken cases */ - /* for example for a tiled image of height 1 with a tile height of 1 and subsampling_hor=subsampling_ver=2 */ - /* In that case, libjpeg will only fill the 8 first lines of the 16 lines */ - /* See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844 */ - /* Even if this case is allowed (?), its handling is broken because OJPEGPreDecode() should also likely */ - /* reset subsampling_convert_state to 0 when changing tile. */ - sp->subsampling_convert_ycbcrbuf=_TIFFcallocExt(tif, 1, sp->subsampling_convert_ycbcrbuflen); - if (sp->subsampling_convert_ycbcrbuf==0) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf; - sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen; - sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen; - sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines; - sp->subsampling_convert_ycbcrimage=_TIFFmallocExt(tif, sp->subsampling_convert_ycbcrimagelen*sizeof(uint8_t*)); - if (sp->subsampling_convert_ycbcrimage==0) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - m=sp->subsampling_convert_ycbcrimage; - *m++=(uint8_t*)(sp->subsampling_convert_ycbcrimage + 3); - *m++=(uint8_t*)(sp->subsampling_convert_ycbcrimage + 3 + sp->subsampling_convert_ylines); - *m++=(uint8_t*)(sp->subsampling_convert_ycbcrimage + 3 + sp->subsampling_convert_ylines + sp->subsampling_convert_clines); - for (n=0; n<sp->subsampling_convert_ylines; n++) - *m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen; - for (n=0; n<sp->subsampling_convert_clines; n++) - *m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen; - for (n=0; n<sp->subsampling_convert_clines; n++) - *m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen; - sp->subsampling_convert_clinelenout=sp->strile_width/sp->subsampling_hor + ((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0); - sp->subsampling_convert_state=0; - sp->error_in_raw_data_decoding=0; - sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2); - sp->lines_per_strile=sp->strile_length/sp->subsampling_ver + ((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0); - sp->subsampling_convert_log=1; - } - } - else - { - sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN; - sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN; - sp->libjpeg_jpeg_query_style=1; - sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width; - sp->lines_per_strile=sp->strile_length; - } - if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0) - return(0); - if(sp->libjpeg_jpeg_decompress_struct.image_width != sp->strile_width ) { - TIFFErrorExtR(tif,module, - "jpeg_start_decompress() returned image_width = %u, " - "expected %"PRIu32, - sp->libjpeg_jpeg_decompress_struct.image_width, - sp->strile_width); - return 0; - } - if(sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor != sp->subsampling_hor || - sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor != sp->subsampling_ver) { - TIFFErrorExtR(tif,module, - "jpeg_start_decompress() returned max_h_samp_factor = %d " - "and max_v_samp_factor = %d, expected %"PRIu8" and %"PRIu8, - sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor, - sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor, - sp->subsampling_hor, - sp->subsampling_ver); - return 0; + sp->libjpeg_jpeg_query_style = 0; + if (sp->subsampling_convert_log == 0) + { + assert(sp->subsampling_convert_ycbcrbuf == 0); + assert(sp->subsampling_convert_ycbcrimage == 0); + sp->subsampling_convert_ylinelen = + ((sp->strile_width + sp->subsampling_hor * 8 - 1) / + (sp->subsampling_hor * 8) * sp->subsampling_hor * 8); + sp->subsampling_convert_ylines = sp->subsampling_ver * 8; + sp->subsampling_convert_clinelen = + sp->subsampling_convert_ylinelen / sp->subsampling_hor; + sp->subsampling_convert_clines = 8; + sp->subsampling_convert_ybuflen = sp->subsampling_convert_ylinelen * + sp->subsampling_convert_ylines; + sp->subsampling_convert_cbuflen = sp->subsampling_convert_clinelen * + sp->subsampling_convert_clines; + sp->subsampling_convert_ycbcrbuflen = + sp->subsampling_convert_ybuflen + + 2 * sp->subsampling_convert_cbuflen; + /* The calloc is not normally necessary, except in some edge/broken + * cases */ + /* for example for a tiled image of height 1 with a tile height of 1 + * and subsampling_hor=subsampling_ver=2 */ + /* In that case, libjpeg will only fill the 8 first lines of the 16 + * lines */ + /* See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=16844 + */ + /* Even if this case is allowed (?), its handling is broken because + * OJPEGPreDecode() should also likely */ + /* reset subsampling_convert_state to 0 when changing tile. */ + sp->subsampling_convert_ycbcrbuf = + _TIFFcallocExt(tif, 1, sp->subsampling_convert_ycbcrbuflen); + if (sp->subsampling_convert_ycbcrbuf == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + sp->subsampling_convert_ybuf = sp->subsampling_convert_ycbcrbuf; + sp->subsampling_convert_cbbuf = + sp->subsampling_convert_ybuf + sp->subsampling_convert_ybuflen; + sp->subsampling_convert_crbuf = + sp->subsampling_convert_cbbuf + sp->subsampling_convert_cbuflen; + sp->subsampling_convert_ycbcrimagelen = + 3 + sp->subsampling_convert_ylines + + 2 * sp->subsampling_convert_clines; + sp->subsampling_convert_ycbcrimage = _TIFFmallocExt( + tif, sp->subsampling_convert_ycbcrimagelen * sizeof(uint8_t *)); + if (sp->subsampling_convert_ycbcrimage == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + m = sp->subsampling_convert_ycbcrimage; + *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3); + *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3 + + sp->subsampling_convert_ylines); + *m++ = (uint8_t *)(sp->subsampling_convert_ycbcrimage + 3 + + sp->subsampling_convert_ylines + + sp->subsampling_convert_clines); + for (n = 0; n < sp->subsampling_convert_ylines; n++) + *m++ = sp->subsampling_convert_ybuf + + n * sp->subsampling_convert_ylinelen; + for (n = 0; n < sp->subsampling_convert_clines; n++) + *m++ = sp->subsampling_convert_cbbuf + + n * sp->subsampling_convert_clinelen; + for (n = 0; n < sp->subsampling_convert_clines; n++) + *m++ = sp->subsampling_convert_crbuf + + n * sp->subsampling_convert_clinelen; + sp->subsampling_convert_clinelenout = + sp->strile_width / sp->subsampling_hor + + ((sp->strile_width % sp->subsampling_hor) != 0 ? 1 : 0); + sp->subsampling_convert_state = 0; + sp->error_in_raw_data_decoding = 0; + sp->bytes_per_line = + sp->subsampling_convert_clinelenout * + (sp->subsampling_ver * sp->subsampling_hor + 2); + sp->lines_per_strile = + sp->strile_length / sp->subsampling_ver + + ((sp->strile_length % sp->subsampling_ver) != 0 ? 1 : 0); + sp->subsampling_convert_log = 1; } + } + else + { + sp->libjpeg_jpeg_decompress_struct.jpeg_color_space = JCS_UNKNOWN; + sp->libjpeg_jpeg_decompress_struct.out_color_space = JCS_UNKNOWN; + sp->libjpeg_jpeg_query_style = 1; + sp->bytes_per_line = sp->samples_per_pixel_per_plane * sp->strile_width; + sp->lines_per_strile = sp->strile_length; + } + if (jpeg_start_decompress_encap(sp, + &(sp->libjpeg_jpeg_decompress_struct)) == 0) + return (0); + if (sp->libjpeg_jpeg_decompress_struct.image_width != sp->strile_width) + { + TIFFErrorExtR(tif, module, + "jpeg_start_decompress() returned image_width = %u, " + "expected %" PRIu32, + sp->libjpeg_jpeg_decompress_struct.image_width, + sp->strile_width); + return 0; + } + if (sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor != + sp->subsampling_hor || + sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor != + sp->subsampling_ver) + { + TIFFErrorExtR(tif, module, + "jpeg_start_decompress() returned max_h_samp_factor = %d " + "and max_v_samp_factor = %d, expected %" PRIu8 + " and %" PRIu8, + sp->libjpeg_jpeg_decompress_struct.max_h_samp_factor, + sp->libjpeg_jpeg_decompress_struct.max_v_samp_factor, + sp->subsampling_hor, sp->subsampling_ver); + return 0; + } + + sp->writeheader_done = 1; + return (1); +} - sp->writeheader_done=1; - return(1); +static void OJPEGLibjpegSessionAbort(TIFF *tif) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(sp->libjpeg_session_active != 0); + jpeg_destroy((jpeg_common_struct *)(&(sp->libjpeg_jpeg_decompress_struct))); + sp->libjpeg_session_active = 0; } -static void -OJPEGLibjpegSessionAbort(TIFF* tif) +static int OJPEGReadHeaderInfoSec(TIFF *tif) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(sp->libjpeg_session_active!=0); - jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct))); - sp->libjpeg_session_active=0; + static const char module[] = "OJPEGReadHeaderInfoSec"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + uint16_t n; + uint8_t o; + if (sp->file_size == 0) + sp->file_size = TIFFGetFileSize(tif); + if (sp->jpeg_interchange_format != 0) + { + if (sp->jpeg_interchange_format >= sp->file_size) + { + sp->jpeg_interchange_format = 0; + sp->jpeg_interchange_format_length = 0; + } + else + { + if ((sp->jpeg_interchange_format_length == 0) || + (sp->jpeg_interchange_format > + UINT64_MAX - sp->jpeg_interchange_format_length) || + (sp->jpeg_interchange_format + + sp->jpeg_interchange_format_length > + sp->file_size)) + sp->jpeg_interchange_format_length = + sp->file_size - sp->jpeg_interchange_format; + } + } + sp->in_buffer_source = osibsNotSetYet; + sp->in_buffer_next_strile = 0; + sp->in_buffer_strile_count = tif->tif_dir.td_nstrips; + sp->in_buffer_file_togo = 0; + sp->in_buffer_togo = 0; + do + { + if (OJPEGReadBytePeek(sp, &m) == 0) + return (0); + if (m != 255) + break; + OJPEGReadByteAdvance(sp); + do + { + if (OJPEGReadByte(sp, &m) == 0) + return (0); + } while (m == 255); + switch (m) + { + case JPEG_MARKER_SOI: + /* this type of marker has no data, and should be skipped */ + break; + case JPEG_MARKER_COM: + case JPEG_MARKER_APP0: + case JPEG_MARKER_APP0 + 1: + case JPEG_MARKER_APP0 + 2: + case JPEG_MARKER_APP0 + 3: + case JPEG_MARKER_APP0 + 4: + case JPEG_MARKER_APP0 + 5: + case JPEG_MARKER_APP0 + 6: + case JPEG_MARKER_APP0 + 7: + case JPEG_MARKER_APP0 + 8: + case JPEG_MARKER_APP0 + 9: + case JPEG_MARKER_APP0 + 10: + case JPEG_MARKER_APP0 + 11: + case JPEG_MARKER_APP0 + 12: + case JPEG_MARKER_APP0 + 13: + case JPEG_MARKER_APP0 + 14: + case JPEG_MARKER_APP0 + 15: + /* this type of marker has data, but it has no use to us (and no + * place here) and should be skipped */ + if (OJPEGReadWord(sp, &n) == 0) + return (0); + if (n < 2) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt JPEG data"); + return (0); + } + if (n > 2) + OJPEGReadSkip(sp, n - 2); + break; + case JPEG_MARKER_DRI: + if (OJPEGReadHeaderInfoSecStreamDri(tif) == 0) + return (0); + break; + case JPEG_MARKER_DQT: + if (OJPEGReadHeaderInfoSecStreamDqt(tif) == 0) + return (0); + break; + case JPEG_MARKER_DHT: + if (OJPEGReadHeaderInfoSecStreamDht(tif) == 0) + return (0); + break; + case JPEG_MARKER_SOF0: + case JPEG_MARKER_SOF1: + case JPEG_MARKER_SOF3: + if (OJPEGReadHeaderInfoSecStreamSof(tif, m) == 0) + return (0); + if (sp->subsamplingcorrect != 0) + return (1); + break; + case JPEG_MARKER_SOS: + if (sp->subsamplingcorrect != 0) + return (1); + assert(sp->plane_sample_offset == 0); + if (OJPEGReadHeaderInfoSecStreamSos(tif) == 0) + return (0); + break; + default: + TIFFErrorExtR(tif, module, + "Unknown marker type %" PRIu8 " in JPEG data", m); + return (0); + } + } while (m != JPEG_MARKER_SOS); + if (sp->subsamplingcorrect) + return (1); + if (sp->sof_log == 0) + { + if (OJPEGReadHeaderInfoSecTablesQTable(tif) == 0) + return (0); + sp->sof_marker_id = JPEG_MARKER_SOF0; + for (o = 0; o < sp->samples_per_pixel; o++) + sp->sof_c[o] = o; + sp->sof_hv[0] = ((sp->subsampling_hor << 4) | sp->subsampling_ver); + for (o = 1; o < sp->samples_per_pixel; o++) + sp->sof_hv[o] = 17; + sp->sof_x = sp->strile_width; + sp->sof_y = sp->strile_length_total; + sp->sof_log = 1; + if (OJPEGReadHeaderInfoSecTablesDcTable(tif) == 0) + return (0); + if (OJPEGReadHeaderInfoSecTablesAcTable(tif) == 0) + return (0); + for (o = 1; o < sp->samples_per_pixel; o++) + sp->sos_cs[o] = o; + } + return (1); } -static int -OJPEGReadHeaderInfoSec(TIFF* tif) -{ - static const char module[]="OJPEGReadHeaderInfoSec"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t m; - uint16_t n; - uint8_t o; - if (sp->file_size==0) - sp->file_size=TIFFGetFileSize(tif); - if (sp->jpeg_interchange_format!=0) - { - if (sp->jpeg_interchange_format>=sp->file_size) - { - sp->jpeg_interchange_format=0; - sp->jpeg_interchange_format_length=0; - } - else - { - if ((sp->jpeg_interchange_format_length==0) || - (sp->jpeg_interchange_format > UINT64_MAX - sp->jpeg_interchange_format_length) || - (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size)) - sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format; - } - } - sp->in_buffer_source=osibsNotSetYet; - sp->in_buffer_next_strile=0; - sp->in_buffer_strile_count=tif->tif_dir.td_nstrips; - sp->in_buffer_file_togo=0; - sp->in_buffer_togo=0; - do - { - if (OJPEGReadBytePeek(sp,&m)==0) - return(0); - if (m!=255) - break; - OJPEGReadByteAdvance(sp); - do - { - if (OJPEGReadByte(sp,&m)==0) - return(0); - } while(m==255); - switch(m) - { - case JPEG_MARKER_SOI: - /* this type of marker has no data, and should be skipped */ - break; - case JPEG_MARKER_COM: - case JPEG_MARKER_APP0: - case JPEG_MARKER_APP0+1: - case JPEG_MARKER_APP0+2: - case JPEG_MARKER_APP0+3: - case JPEG_MARKER_APP0+4: - case JPEG_MARKER_APP0+5: - case JPEG_MARKER_APP0+6: - case JPEG_MARKER_APP0+7: - case JPEG_MARKER_APP0+8: - case JPEG_MARKER_APP0+9: - case JPEG_MARKER_APP0+10: - case JPEG_MARKER_APP0+11: - case JPEG_MARKER_APP0+12: - case JPEG_MARKER_APP0+13: - case JPEG_MARKER_APP0+14: - case JPEG_MARKER_APP0+15: - /* this type of marker has data, but it has no use to us (and no place here) and should be skipped */ - if (OJPEGReadWord(sp,&n)==0) - return(0); - if (n<2) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExtR(tif,module,"Corrupt JPEG data"); - return(0); - } - if (n>2) - OJPEGReadSkip(sp,n-2); - break; - case JPEG_MARKER_DRI: - if (OJPEGReadHeaderInfoSecStreamDri(tif)==0) - return(0); - break; - case JPEG_MARKER_DQT: - if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0) - return(0); - break; - case JPEG_MARKER_DHT: - if (OJPEGReadHeaderInfoSecStreamDht(tif)==0) - return(0); - break; - case JPEG_MARKER_SOF0: - case JPEG_MARKER_SOF1: - case JPEG_MARKER_SOF3: - if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0) - return(0); - if (sp->subsamplingcorrect!=0) - return(1); - break; - case JPEG_MARKER_SOS: - if (sp->subsamplingcorrect!=0) - return(1); - assert(sp->plane_sample_offset==0); - if (OJPEGReadHeaderInfoSecStreamSos(tif)==0) - return(0); - break; - default: - TIFFErrorExtR(tif,module,"Unknown marker type %"PRIu8" in JPEG data", m); - return(0); - } - } while(m!=JPEG_MARKER_SOS); - if (sp->subsamplingcorrect) - return(1); - if (sp->sof_log==0) - { - if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0) - return(0); - sp->sof_marker_id=JPEG_MARKER_SOF0; - for (o=0; o<sp->samples_per_pixel; o++) - sp->sof_c[o]=o; - sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver); - for (o=1; o<sp->samples_per_pixel; o++) - sp->sof_hv[o]=17; - sp->sof_x=sp->strile_width; - sp->sof_y=sp->strile_length_total; - sp->sof_log=1; - if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0) - return(0); - if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0) - return(0); - for (o=1; o<sp->samples_per_pixel; o++) - sp->sos_cs[o]=o; - } - return(1); +static int OJPEGReadHeaderInfoSecStreamDri(TIFF *tif) +{ + /* This could easily cause trouble in some cases... but no such cases have + occurred so far */ + static const char module[] = "OJPEGReadHeaderInfoSecStreamDri"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint16_t m; + if (OJPEGReadWord(sp, &m) == 0) + return (0); + if (m != 4) + { + TIFFErrorExtR(tif, module, "Corrupt DRI marker in JPEG data"); + return (0); + } + if (OJPEGReadWord(sp, &m) == 0) + return (0); + sp->restart_interval = m; + return (1); } -static int -OJPEGReadHeaderInfoSecStreamDri(TIFF* tif) -{ - /* This could easily cause trouble in some cases... but no such cases have - occurred so far */ - static const char module[]="OJPEGReadHeaderInfoSecStreamDri"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint16_t m; - if (OJPEGReadWord(sp,&m)==0) - return(0); - if (m!=4) - { - TIFFErrorExtR(tif,module,"Corrupt DRI marker in JPEG data"); - return(0); - } - if (OJPEGReadWord(sp,&m)==0) - return(0); - sp->restart_interval=m; - return(1); +static int OJPEGReadHeaderInfoSecStreamDqt(TIFF *tif) +{ + /* this is a table marker, and it is to be saved as a whole for exact + * pushing on the jpeg stream later on */ + static const char module[] = "OJPEGReadHeaderInfoSecStreamDqt"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint16_t m; + uint32_t na; + uint8_t *nb; + uint8_t o; + if (OJPEGReadWord(sp, &m) == 0) + return (0); + if (m <= 2) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data"); + return (0); + } + if (sp->subsamplingcorrect != 0) + OJPEGReadSkip(sp, m - 2); + else + { + m -= 2; + do + { + if (m < 65) + { + TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data"); + return (0); + } + na = sizeof(uint32_t) + 69; + nb = _TIFFmallocExt(tif, na); + if (nb == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + *(uint32_t *)nb = na; + nb[sizeof(uint32_t)] = 255; + nb[sizeof(uint32_t) + 1] = JPEG_MARKER_DQT; + nb[sizeof(uint32_t) + 2] = 0; + nb[sizeof(uint32_t) + 3] = 67; + if (OJPEGReadBlock(sp, 65, &nb[sizeof(uint32_t) + 4]) == 0) + { + _TIFFfreeExt(tif, nb); + return (0); + } + o = nb[sizeof(uint32_t) + 4] & 15; + if (3 < o) + { + TIFFErrorExtR(tif, module, "Corrupt DQT marker in JPEG data"); + _TIFFfreeExt(tif, nb); + return (0); + } + if (sp->qtable[o] != 0) + _TIFFfreeExt(tif, sp->qtable[o]); + sp->qtable[o] = nb; + m -= 65; + } while (m > 0); + } + return (1); } -static int -OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif) -{ - /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */ - static const char module[]="OJPEGReadHeaderInfoSecStreamDqt"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint16_t m; - uint32_t na; - uint8_t* nb; - uint8_t o; - if (OJPEGReadWord(sp,&m)==0) - return(0); - if (m<=2) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExtR(tif,module,"Corrupt DQT marker in JPEG data"); - return(0); - } - if (sp->subsamplingcorrect!=0) - OJPEGReadSkip(sp,m-2); - else - { - m-=2; - do - { - if (m<65) - { - TIFFErrorExtR(tif,module,"Corrupt DQT marker in JPEG data"); - return(0); - } - na= sizeof(uint32_t) + 69; - nb=_TIFFmallocExt(tif, na); - if (nb==0) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - *(uint32_t*)nb=na; - nb[sizeof(uint32_t)]=255; - nb[sizeof(uint32_t) + 1]=JPEG_MARKER_DQT; - nb[sizeof(uint32_t) + 2]=0; - nb[sizeof(uint32_t) + 3]=67; - if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32_t) + 4]) == 0) { - _TIFFfreeExt(tif, nb); - return(0); - } - o= nb[sizeof(uint32_t) + 4] & 15; - if (3<o) - { - TIFFErrorExtR(tif,module,"Corrupt DQT marker in JPEG data"); - _TIFFfreeExt(tif, nb); - return(0); - } - if (sp->qtable[o]!=0) - _TIFFfreeExt(tif, sp->qtable[o]); - sp->qtable[o]=nb; - m-=65; - } while(m>0); - } - return(1); +static int OJPEGReadHeaderInfoSecStreamDht(TIFF *tif) +{ + /* this is a table marker, and it is to be saved as a whole for exact + * pushing on the jpeg stream later on */ + /* TODO: the following assumes there is only one table in this marker... but + * i'm not quite sure that assumption is guaranteed correct */ + static const char module[] = "OJPEGReadHeaderInfoSecStreamDht"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint16_t m; + uint32_t na; + uint8_t *nb; + uint8_t o; + if (OJPEGReadWord(sp, &m) == 0) + return (0); + if (m <= 2) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); + return (0); + } + if (sp->subsamplingcorrect != 0) + { + OJPEGReadSkip(sp, m - 2); + } + else + { + na = sizeof(uint32_t) + 2 + m; + nb = _TIFFmallocExt(tif, na); + if (nb == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + *(uint32_t *)nb = na; + nb[sizeof(uint32_t)] = 255; + nb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT; + nb[sizeof(uint32_t) + 2] = (m >> 8); + nb[sizeof(uint32_t) + 3] = (m & 255); + if (OJPEGReadBlock(sp, m - 2, &nb[sizeof(uint32_t) + 4]) == 0) + { + _TIFFfreeExt(tif, nb); + return (0); + } + o = nb[sizeof(uint32_t) + 4]; + if ((o & 240) == 0) + { + if (3 < o) + { + TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); + _TIFFfreeExt(tif, nb); + return (0); + } + if (sp->dctable[o] != 0) + _TIFFfreeExt(tif, sp->dctable[o]); + sp->dctable[o] = nb; + } + else + { + if ((o & 240) != 16) + { + TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); + _TIFFfreeExt(tif, nb); + return (0); + } + o &= 15; + if (3 < o) + { + TIFFErrorExtR(tif, module, "Corrupt DHT marker in JPEG data"); + _TIFFfreeExt(tif, nb); + return (0); + } + if (sp->actable[o] != 0) + _TIFFfreeExt(tif, sp->actable[o]); + sp->actable[o] = nb; + } + } + return (1); } -static int -OJPEGReadHeaderInfoSecStreamDht(TIFF* tif) -{ - /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */ - /* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */ - static const char module[]="OJPEGReadHeaderInfoSecStreamDht"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint16_t m; - uint32_t na; - uint8_t* nb; - uint8_t o; - if (OJPEGReadWord(sp,&m)==0) - return(0); - if (m<=2) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExtR(tif,module,"Corrupt DHT marker in JPEG data"); - return(0); - } - if (sp->subsamplingcorrect!=0) - { - OJPEGReadSkip(sp,m-2); - } - else - { - na= sizeof(uint32_t) + 2 + m; - nb=_TIFFmallocExt(tif, na); - if (nb==0) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - *(uint32_t*)nb=na; - nb[sizeof(uint32_t)]=255; - nb[sizeof(uint32_t) + 1]=JPEG_MARKER_DHT; - nb[sizeof(uint32_t) + 2]=(m >> 8); - nb[sizeof(uint32_t) + 3]=(m & 255); - if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32_t) + 4]) == 0) { - _TIFFfreeExt(tif, nb); - return(0); +static int OJPEGReadHeaderInfoSecStreamSof(TIFF *tif, uint8_t marker_id) +{ + /* this marker needs to be checked, and part of its data needs to be saved + * for regeneration later on */ + static const char module[] = "OJPEGReadHeaderInfoSecStreamSof"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint16_t m; + uint16_t n; + uint8_t o; + uint16_t p; + uint16_t q; + if (sp->sof_log != 0) + { + TIFFErrorExtR(tif, module, "Corrupt JPEG data"); + return (0); + } + if (sp->subsamplingcorrect == 0) + sp->sof_marker_id = marker_id; + /* Lf: data length */ + if (OJPEGReadWord(sp, &m) == 0) + return (0); + if (m < 11) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data"); + return (0); + } + m -= 8; + if (m % 3 != 0) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data"); + return (0); + } + n = m / 3; + if (sp->subsamplingcorrect == 0) + { + if (n != sp->samples_per_pixel) + { + TIFFErrorExtR( + tif, module, + "JPEG compressed data indicates unexpected number of samples"); + return (0); + } + } + /* P: Sample precision */ + if (OJPEGReadByte(sp, &o) == 0) + return (0); + if (o != 8) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, + "JPEG compressed data indicates unexpected number of " + "bits per sample"); + return (0); + } + /* Y: Number of lines, X: Number of samples per line */ + if (sp->subsamplingcorrect) + OJPEGReadSkip(sp, 4); + else + { + /* Y: Number of lines */ + if (OJPEGReadWord(sp, &p) == 0) + return (0); + if (((uint32_t)p < sp->image_length) && + ((uint32_t)p < sp->strile_length_total)) + { + TIFFErrorExtR(tif, module, + "JPEG compressed data indicates unexpected height"); + return (0); + } + sp->sof_y = p; + /* X: Number of samples per line */ + if (OJPEGReadWord(sp, &p) == 0) + return (0); + if (((uint32_t)p < sp->image_width) && ((uint32_t)p < sp->strile_width)) + { + TIFFErrorExtR(tif, module, + "JPEG compressed data indicates unexpected width"); + return (0); + } + if ((uint32_t)p > sp->strile_width) + { + TIFFErrorExtR(tif, module, + "JPEG compressed data image width exceeds expected " + "image width"); + return (0); + } + sp->sof_x = p; + } + /* Nf: Number of image components in frame */ + if (OJPEGReadByte(sp, &o) == 0) + return (0); + if (o != n) + { + if (sp->subsamplingcorrect == 0) + TIFFErrorExtR(tif, module, "Corrupt SOF marker in JPEG data"); + return (0); + } + /* per component stuff */ + /* TODO: double-check that flow implies that n cannot be as big as to make + * us overflow sof_c, sof_hv and sof_tq arrays */ + for (q = 0; q < n; q++) + { + /* C: Component identifier */ + if (OJPEGReadByte(sp, &o) == 0) + return (0); + if (sp->subsamplingcorrect == 0) + sp->sof_c[q] = o; + /* H: Horizontal sampling factor, and V: Vertical sampling factor */ + if (OJPEGReadByte(sp, &o) == 0) + return (0); + if (sp->subsamplingcorrect != 0) + { + if (q == 0) + { + sp->subsampling_hor = (o >> 4); + sp->subsampling_ver = (o & 15); + if (((sp->subsampling_hor != 1) && (sp->subsampling_hor != 2) && + (sp->subsampling_hor != 4)) || + ((sp->subsampling_ver != 1) && (sp->subsampling_ver != 2) && + (sp->subsampling_ver != 4))) + sp->subsampling_force_desubsampling_inside_decompression = + 1; + } + else + { + if (o != 17) + sp->subsampling_force_desubsampling_inside_decompression = + 1; + } + } + else + { + sp->sof_hv[q] = o; + if (sp->subsampling_force_desubsampling_inside_decompression == 0) + { + if (q == 0) + { + if (o != ((sp->subsampling_hor << 4) | sp->subsampling_ver)) + { + TIFFErrorExtR(tif, module, + "JPEG compressed data indicates " + "unexpected subsampling values"); + return (0); + } } - o=nb[sizeof(uint32_t) + 4]; - if ((o&240)==0) - { - if (3<o) - { - TIFFErrorExtR(tif,module,"Corrupt DHT marker in JPEG data"); - _TIFFfreeExt(tif, nb); - return(0); - } - if (sp->dctable[o]!=0) - _TIFFfreeExt(tif, sp->dctable[o]); - sp->dctable[o]=nb; - } - else - { - if ((o&240)!=16) - { - TIFFErrorExtR(tif,module,"Corrupt DHT marker in JPEG data"); - _TIFFfreeExt(tif, nb); - return(0); - } - o&=15; - if (3<o) - { - TIFFErrorExtR(tif,module,"Corrupt DHT marker in JPEG data"); - _TIFFfreeExt(tif, nb); - return(0); - } - if (sp->actable[o]!=0) - _TIFFfreeExt(tif, sp->actable[o]); - sp->actable[o]=nb; - } - } - return(1); + else + { + if (o != 17) + { + TIFFErrorExtR(tif, module, + "JPEG compressed data indicates " + "unexpected subsampling values"); + return (0); + } + } + } + } + /* Tq: Quantization table destination selector */ + if (OJPEGReadByte(sp, &o) == 0) + return (0); + if (sp->subsamplingcorrect == 0) + sp->sof_tq[q] = o; + } + if (sp->subsamplingcorrect == 0) + sp->sof_log = 1; + return (1); } -static int -OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8_t marker_id) -{ - /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */ - static const char module[]="OJPEGReadHeaderInfoSecStreamSof"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint16_t m; - uint16_t n; - uint8_t o; - uint16_t p; - uint16_t q; - if (sp->sof_log!=0) - { - TIFFErrorExtR(tif,module,"Corrupt JPEG data"); - return(0); - } - if (sp->subsamplingcorrect==0) - sp->sof_marker_id=marker_id; - /* Lf: data length */ - if (OJPEGReadWord(sp,&m)==0) - return(0); - if (m<11) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExtR(tif,module,"Corrupt SOF marker in JPEG data"); - return(0); - } - m-=8; - if (m%3!=0) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExtR(tif,module,"Corrupt SOF marker in JPEG data"); - return(0); - } - n=m/3; - if (sp->subsamplingcorrect==0) - { - if (n!=sp->samples_per_pixel) - { - TIFFErrorExtR(tif,module,"JPEG compressed data indicates unexpected number of samples"); - return(0); - } - } - /* P: Sample precision */ - if (OJPEGReadByte(sp,&o)==0) - return(0); - if (o!=8) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExtR(tif,module,"JPEG compressed data indicates unexpected number of bits per sample"); - return(0); - } - /* Y: Number of lines, X: Number of samples per line */ - if (sp->subsamplingcorrect) - OJPEGReadSkip(sp,4); - else - { - /* Y: Number of lines */ - if (OJPEGReadWord(sp,&p)==0) - return(0); - if (((uint32_t)p < sp->image_length) && ((uint32_t)p < sp->strile_length_total)) - { - TIFFErrorExtR(tif,module,"JPEG compressed data indicates unexpected height"); - return(0); - } - sp->sof_y=p; - /* X: Number of samples per line */ - if (OJPEGReadWord(sp,&p)==0) - return(0); - if (((uint32_t)p < sp->image_width) && ((uint32_t)p < sp->strile_width)) - { - TIFFErrorExtR(tif,module,"JPEG compressed data indicates unexpected width"); - return(0); - } - if ((uint32_t)p > sp->strile_width) - { - TIFFErrorExtR(tif,module,"JPEG compressed data image width exceeds expected image width"); - return(0); - } - sp->sof_x=p; - } - /* Nf: Number of image components in frame */ - if (OJPEGReadByte(sp,&o)==0) - return(0); - if (o!=n) - { - if (sp->subsamplingcorrect==0) - TIFFErrorExtR(tif,module,"Corrupt SOF marker in JPEG data"); - return(0); - } - /* per component stuff */ - /* TODO: double-check that flow implies that n cannot be as big as to make us overflow sof_c, sof_hv and sof_tq arrays */ - for (q=0; q<n; q++) - { - /* C: Component identifier */ - if (OJPEGReadByte(sp,&o)==0) - return(0); - if (sp->subsamplingcorrect==0) - sp->sof_c[q]=o; - /* H: Horizontal sampling factor, and V: Vertical sampling factor */ - if (OJPEGReadByte(sp,&o)==0) - return(0); - if (sp->subsamplingcorrect!=0) - { - if (q==0) - { - sp->subsampling_hor=(o>>4); - sp->subsampling_ver=(o&15); - if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) || - ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4))) - sp->subsampling_force_desubsampling_inside_decompression=1; - } - else - { - if (o!=17) - sp->subsampling_force_desubsampling_inside_decompression=1; - } - } - else - { - sp->sof_hv[q]=o; - if (sp->subsampling_force_desubsampling_inside_decompression==0) - { - if (q==0) - { - if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver)) - { - TIFFErrorExtR(tif,module,"JPEG compressed data indicates unexpected subsampling values"); - return(0); - } - } - else - { - if (o!=17) - { - TIFFErrorExtR(tif,module,"JPEG compressed data indicates unexpected subsampling values"); - return(0); - } - } - } - } - /* Tq: Quantization table destination selector */ - if (OJPEGReadByte(sp,&o)==0) - return(0); - if (sp->subsamplingcorrect==0) - sp->sof_tq[q]=o; - } - if (sp->subsamplingcorrect==0) - sp->sof_log=1; - return(1); +static int OJPEGReadHeaderInfoSecStreamSos(TIFF *tif) +{ + /* this marker needs to be checked, and part of its data needs to be saved + * for regeneration later on */ + static const char module[] = "OJPEGReadHeaderInfoSecStreamSos"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint16_t m; + uint8_t n; + uint8_t o; + assert(sp->subsamplingcorrect == 0); + if (sp->sof_log == 0) + { + TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data"); + return (0); + } + /* Ls */ + if (OJPEGReadWord(sp, &m) == 0) + return (0); + if (m != 6 + sp->samples_per_pixel_per_plane * 2) + { + TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data"); + return (0); + } + /* Ns */ + if (OJPEGReadByte(sp, &n) == 0) + return (0); + if (n != sp->samples_per_pixel_per_plane) + { + TIFFErrorExtR(tif, module, "Corrupt SOS marker in JPEG data"); + return (0); + } + /* Cs, Td, and Ta */ + for (o = 0; o < sp->samples_per_pixel_per_plane; o++) + { + /* Cs */ + if (OJPEGReadByte(sp, &n) == 0) + return (0); + sp->sos_cs[sp->plane_sample_offset + o] = n; + /* Td and Ta */ + if (OJPEGReadByte(sp, &n) == 0) + return (0); + sp->sos_tda[sp->plane_sample_offset + o] = n; + } + /* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as + * per LibJpeg source */ + OJPEGReadSkip(sp, 3); + return (1); } -static int -OJPEGReadHeaderInfoSecStreamSos(TIFF* tif) -{ - /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */ - static const char module[]="OJPEGReadHeaderInfoSecStreamSos"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint16_t m; - uint8_t n; - uint8_t o; - assert(sp->subsamplingcorrect==0); - if (sp->sof_log==0) - { - TIFFErrorExtR(tif,module,"Corrupt SOS marker in JPEG data"); - return(0); - } - /* Ls */ - if (OJPEGReadWord(sp,&m)==0) - return(0); - if (m!=6+sp->samples_per_pixel_per_plane*2) - { - TIFFErrorExtR(tif,module,"Corrupt SOS marker in JPEG data"); - return(0); - } - /* Ns */ - if (OJPEGReadByte(sp,&n)==0) - return(0); - if (n!=sp->samples_per_pixel_per_plane) - { - TIFFErrorExtR(tif,module,"Corrupt SOS marker in JPEG data"); - return(0); - } - /* Cs, Td, and Ta */ - for (o=0; o<sp->samples_per_pixel_per_plane; o++) - { - /* Cs */ - if (OJPEGReadByte(sp,&n)==0) - return(0); - sp->sos_cs[sp->plane_sample_offset+o]=n; - /* Td and Ta */ - if (OJPEGReadByte(sp,&n)==0) - return(0); - sp->sos_tda[sp->plane_sample_offset+o]=n; - } - /* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */ - OJPEGReadSkip(sp,3); - return(1); +static int OJPEGReadHeaderInfoSecTablesQTable(TIFF *tif) +{ + static const char module[] = "OJPEGReadHeaderInfoSecTablesQTable"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + uint8_t n; + uint32_t oa; + uint8_t *ob; + uint32_t p; + if (sp->qtable_offset[0] == 0) + { + TIFFErrorExtR(tif, module, "Missing JPEG tables"); + return (0); + } + sp->in_buffer_file_pos_log = 0; + for (m = 0; m < sp->samples_per_pixel; m++) + { + if ((sp->qtable_offset[m] != 0) && + ((m == 0) || (sp->qtable_offset[m] != sp->qtable_offset[m - 1]))) + { + for (n = 0; n < m - 1; n++) + { + if (sp->qtable_offset[m] == sp->qtable_offset[n]) + { + TIFFErrorExtR(tif, module, "Corrupt JpegQTables tag value"); + return (0); + } + } + oa = sizeof(uint32_t) + 69; + ob = _TIFFmallocExt(tif, oa); + if (ob == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + *(uint32_t *)ob = oa; + ob[sizeof(uint32_t)] = 255; + ob[sizeof(uint32_t) + 1] = JPEG_MARKER_DQT; + ob[sizeof(uint32_t) + 2] = 0; + ob[sizeof(uint32_t) + 3] = 67; + ob[sizeof(uint32_t) + 4] = m; + TIFFSeekFile(tif, sp->qtable_offset[m], SEEK_SET); + p = (uint32_t)TIFFReadFile(tif, &ob[sizeof(uint32_t) + 5], 64); + if (p != 64) + { + _TIFFfreeExt(tif, ob); + return (0); + } + if (sp->qtable[m] != 0) + _TIFFfreeExt(tif, sp->qtable[m]); + sp->qtable[m] = ob; + sp->sof_tq[m] = m; + } + else + sp->sof_tq[m] = sp->sof_tq[m - 1]; + } + return (1); } -static int -OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif) -{ - static const char module[]="OJPEGReadHeaderInfoSecTablesQTable"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t m; - uint8_t n; - uint32_t oa; - uint8_t* ob; - uint32_t p; - if (sp->qtable_offset[0]==0) - { - TIFFErrorExtR(tif,module,"Missing JPEG tables"); - return(0); - } - sp->in_buffer_file_pos_log=0; - for (m=0; m<sp->samples_per_pixel; m++) - { - if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1]))) - { - for (n=0; n<m-1; n++) - { - if (sp->qtable_offset[m]==sp->qtable_offset[n]) - { - TIFFErrorExtR(tif,module,"Corrupt JpegQTables tag value"); - return(0); - } - } - oa= sizeof(uint32_t) + 69; - ob=_TIFFmallocExt(tif, oa); - if (ob==0) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - *(uint32_t*)ob=oa; - ob[sizeof(uint32_t)]=255; - ob[sizeof(uint32_t) + 1]=JPEG_MARKER_DQT; - ob[sizeof(uint32_t) + 2]=0; - ob[sizeof(uint32_t) + 3]=67; - ob[sizeof(uint32_t) + 4]=m; - TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); - p=(uint32_t)TIFFReadFile(tif, &ob[sizeof(uint32_t) + 5], 64); - if (p!=64) - { - _TIFFfreeExt(tif, ob); - return(0); - } - if (sp->qtable[m]!=0) - _TIFFfreeExt(tif, sp->qtable[m]); - sp->qtable[m]=ob; - sp->sof_tq[m]=m; - } - else - sp->sof_tq[m]=sp->sof_tq[m-1]; - } - return(1); +static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF *tif) +{ + static const char module[] = "OJPEGReadHeaderInfoSecTablesDcTable"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + uint8_t n; + uint8_t o[16]; + uint32_t p; + uint32_t q; + uint32_t ra; + uint8_t *rb; + if (sp->dctable_offset[0] == 0) + { + TIFFErrorExtR(tif, module, "Missing JPEG tables"); + return (0); + } + sp->in_buffer_file_pos_log = 0; + for (m = 0; m < sp->samples_per_pixel; m++) + { + if ((sp->dctable_offset[m] != 0) && + ((m == 0) || (sp->dctable_offset[m] != sp->dctable_offset[m - 1]))) + { + for (n = 0; n < m - 1; n++) + { + if (sp->dctable_offset[m] == sp->dctable_offset[n]) + { + TIFFErrorExtR(tif, module, + "Corrupt JpegDcTables tag value"); + return (0); + } + } + TIFFSeekFile(tif, sp->dctable_offset[m], SEEK_SET); + p = (uint32_t)TIFFReadFile(tif, o, 16); + if (p != 16) + return (0); + q = 0; + for (n = 0; n < 16; n++) + q += o[n]; + ra = sizeof(uint32_t) + 21 + q; + rb = _TIFFmallocExt(tif, ra); + if (rb == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + *(uint32_t *)rb = ra; + rb[sizeof(uint32_t)] = 255; + rb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT; + rb[sizeof(uint32_t) + 2] = (uint8_t)((19 + q) >> 8); + rb[sizeof(uint32_t) + 3] = ((19 + q) & 255); + rb[sizeof(uint32_t) + 4] = m; + for (n = 0; n < 16; n++) + rb[sizeof(uint32_t) + 5 + n] = o[n]; + p = (uint32_t)TIFFReadFile(tif, &(rb[sizeof(uint32_t) + 21]), q); + if (p != q) + { + _TIFFfreeExt(tif, rb); + return (0); + } + if (sp->dctable[m] != 0) + _TIFFfreeExt(tif, sp->dctable[m]); + sp->dctable[m] = rb; + sp->sos_tda[m] = (m << 4); + } + else + sp->sos_tda[m] = sp->sos_tda[m - 1]; + } + return (1); } -static int -OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif) -{ - static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t m; - uint8_t n; - uint8_t o[16]; - uint32_t p; - uint32_t q; - uint32_t ra; - uint8_t* rb; - if (sp->dctable_offset[0]==0) - { - TIFFErrorExtR(tif,module,"Missing JPEG tables"); - return(0); - } - sp->in_buffer_file_pos_log=0; - for (m=0; m<sp->samples_per_pixel; m++) - { - if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1]))) - { - for (n=0; n<m-1; n++) - { - if (sp->dctable_offset[m]==sp->dctable_offset[n]) - { - TIFFErrorExtR(tif,module,"Corrupt JpegDcTables tag value"); - return(0); - } - } - TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET); - p=(uint32_t)TIFFReadFile(tif, o, 16); - if (p!=16) - return(0); - q=0; - for (n=0; n<16; n++) - q+=o[n]; - ra= sizeof(uint32_t) + 21 + q; - rb=_TIFFmallocExt(tif, ra); - if (rb==0) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - *(uint32_t*)rb=ra; - rb[sizeof(uint32_t)]=255; - rb[sizeof(uint32_t) + 1]=JPEG_MARKER_DHT; - rb[sizeof(uint32_t) + 2]=(uint8_t)((19 + q) >> 8); - rb[sizeof(uint32_t) + 3]=((19 + q) & 255); - rb[sizeof(uint32_t) + 4]=m; - for (n=0; n<16; n++) - rb[sizeof(uint32_t) + 5 + n]=o[n]; - p=(uint32_t)TIFFReadFile(tif, &(rb[sizeof(uint32_t) + 21]), q); - if (p!=q) - { - _TIFFfreeExt(tif, rb); - return(0); - } - if (sp->dctable[m]!=0) - _TIFFfreeExt(tif, sp->dctable[m]); - sp->dctable[m]=rb; - sp->sos_tda[m]=(m<<4); - } - else - sp->sos_tda[m]=sp->sos_tda[m-1]; - } - return(1); +static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF *tif) +{ + static const char module[] = "OJPEGReadHeaderInfoSecTablesAcTable"; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + uint8_t n; + uint8_t o[16]; + uint32_t p; + uint32_t q; + uint32_t ra; + uint8_t *rb; + if (sp->actable_offset[0] == 0) + { + TIFFErrorExtR(tif, module, "Missing JPEG tables"); + return (0); + } + sp->in_buffer_file_pos_log = 0; + for (m = 0; m < sp->samples_per_pixel; m++) + { + if ((sp->actable_offset[m] != 0) && + ((m == 0) || (sp->actable_offset[m] != sp->actable_offset[m - 1]))) + { + for (n = 0; n < m - 1; n++) + { + if (sp->actable_offset[m] == sp->actable_offset[n]) + { + TIFFErrorExtR(tif, module, + "Corrupt JpegAcTables tag value"); + return (0); + } + } + TIFFSeekFile(tif, sp->actable_offset[m], SEEK_SET); + p = (uint32_t)TIFFReadFile(tif, o, 16); + if (p != 16) + return (0); + q = 0; + for (n = 0; n < 16; n++) + q += o[n]; + ra = sizeof(uint32_t) + 21 + q; + rb = _TIFFmallocExt(tif, ra); + if (rb == 0) + { + TIFFErrorExtR(tif, module, "Out of memory"); + return (0); + } + *(uint32_t *)rb = ra; + rb[sizeof(uint32_t)] = 255; + rb[sizeof(uint32_t) + 1] = JPEG_MARKER_DHT; + rb[sizeof(uint32_t) + 2] = (uint8_t)((19 + q) >> 8); + rb[sizeof(uint32_t) + 3] = ((19 + q) & 255); + rb[sizeof(uint32_t) + 4] = (16 | m); + for (n = 0; n < 16; n++) + rb[sizeof(uint32_t) + 5 + n] = o[n]; + p = (uint32_t)TIFFReadFile(tif, &(rb[sizeof(uint32_t) + 21]), q); + if (p != q) + { + _TIFFfreeExt(tif, rb); + return (0); + } + if (sp->actable[m] != 0) + _TIFFfreeExt(tif, sp->actable[m]); + sp->actable[m] = rb; + sp->sos_tda[m] = (sp->sos_tda[m] | m); + } + else + sp->sos_tda[m] = (sp->sos_tda[m] | (sp->sos_tda[m - 1] & 15)); + } + return (1); } -static int -OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif) -{ - static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable"; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t m; - uint8_t n; - uint8_t o[16]; - uint32_t p; - uint32_t q; - uint32_t ra; - uint8_t* rb; - if (sp->actable_offset[0]==0) - { - TIFFErrorExtR(tif,module,"Missing JPEG tables"); - return(0); - } - sp->in_buffer_file_pos_log=0; - for (m=0; m<sp->samples_per_pixel; m++) - { - if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1]))) - { - for (n=0; n<m-1; n++) - { - if (sp->actable_offset[m]==sp->actable_offset[n]) - { - TIFFErrorExtR(tif,module,"Corrupt JpegAcTables tag value"); - return(0); - } - } - TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET); - p=(uint32_t)TIFFReadFile(tif, o, 16); - if (p!=16) - return(0); - q=0; - for (n=0; n<16; n++) - q+=o[n]; - ra= sizeof(uint32_t) + 21 + q; - rb=_TIFFmallocExt(tif, ra); - if (rb==0) - { - TIFFErrorExtR(tif,module,"Out of memory"); - return(0); - } - *(uint32_t*)rb=ra; - rb[sizeof(uint32_t)]=255; - rb[sizeof(uint32_t) + 1]=JPEG_MARKER_DHT; - rb[sizeof(uint32_t) + 2]=(uint8_t)((19 + q) >> 8); - rb[sizeof(uint32_t) + 3]=((19 + q) & 255); - rb[sizeof(uint32_t) + 4]=(16 | m); - for (n=0; n<16; n++) - rb[sizeof(uint32_t) + 5 + n]=o[n]; - p=(uint32_t)TIFFReadFile(tif, &(rb[sizeof(uint32_t) + 21]), q); - if (p!=q) +static int OJPEGReadBufferFill(OJPEGState *sp) +{ + uint16_t m; + tmsize_t n; + /* TODO: double-check: when subsamplingcorrect is set, no call to + * TIFFErrorExt or TIFFWarningExt should be made in any other case, seek or + * read errors should be passed through */ + do + { + if (sp->in_buffer_file_togo != 0) + { + if (sp->in_buffer_file_pos_log == 0) + { + TIFFSeekFile(sp->tif, sp->in_buffer_file_pos, SEEK_SET); + sp->in_buffer_file_pos_log = 1; + } + m = OJPEG_BUFFER; + if ((uint64_t)m > sp->in_buffer_file_togo) + m = (uint16_t)sp->in_buffer_file_togo; + n = TIFFReadFile(sp->tif, sp->in_buffer, (tmsize_t)m); + if (n == 0) + return (0); + assert(n > 0); + assert(n <= OJPEG_BUFFER); + assert(n < 65536); + assert((uint64_t)n <= sp->in_buffer_file_togo); + m = (uint16_t)n; + sp->in_buffer_togo = m; + sp->in_buffer_cur = sp->in_buffer; + sp->in_buffer_file_togo -= m; + sp->in_buffer_file_pos += m; + break; + } + sp->in_buffer_file_pos_log = 0; + switch (sp->in_buffer_source) + { + case osibsNotSetYet: + if (sp->jpeg_interchange_format != 0) + { + sp->in_buffer_file_pos = sp->jpeg_interchange_format; + sp->in_buffer_file_togo = + sp->jpeg_interchange_format_length; + } + sp->in_buffer_source = osibsJpegInterchangeFormat; + break; + case osibsJpegInterchangeFormat: + sp->in_buffer_source = osibsStrile; + break; + case osibsStrile: + if (sp->in_buffer_next_strile == sp->in_buffer_strile_count) + sp->in_buffer_source = osibsEof; + else + { + int err = 0; + sp->in_buffer_file_pos = TIFFGetStrileOffsetWithErr( + sp->tif, sp->in_buffer_next_strile, &err); + if (err) + return 0; + if (sp->in_buffer_file_pos != 0) + { + uint64_t bytecount = TIFFGetStrileByteCountWithErr( + sp->tif, sp->in_buffer_next_strile, &err); + if (err) + return 0; + if (sp->in_buffer_file_pos >= sp->file_size) + sp->in_buffer_file_pos = 0; + else if (bytecount == 0) + sp->in_buffer_file_togo = + sp->file_size - sp->in_buffer_file_pos; + else { - _TIFFfreeExt(tif, rb); - return(0); + sp->in_buffer_file_togo = bytecount; + if (sp->in_buffer_file_togo == 0) + sp->in_buffer_file_pos = 0; + else if (sp->in_buffer_file_pos > + UINT64_MAX - sp->in_buffer_file_togo || + sp->in_buffer_file_pos + + sp->in_buffer_file_togo > + sp->file_size) + sp->in_buffer_file_togo = + sp->file_size - sp->in_buffer_file_pos; } - if (sp->actable[m]!=0) - _TIFFfreeExt(tif, sp->actable[m]); - sp->actable[m]=rb; - sp->sos_tda[m]=(sp->sos_tda[m]|m); - } - else - sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15)); - } - return(1); -} - -static int -OJPEGReadBufferFill(OJPEGState* sp) -{ - uint16_t m; - tmsize_t n; - /* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made - * in any other case, seek or read errors should be passed through */ - do - { - if (sp->in_buffer_file_togo!=0) - { - if (sp->in_buffer_file_pos_log==0) - { - TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET); - sp->in_buffer_file_pos_log=1; - } - m=OJPEG_BUFFER; - if ((uint64_t)m > sp->in_buffer_file_togo) - m=(uint16_t)sp->in_buffer_file_togo; - n=TIFFReadFile(sp->tif,sp->in_buffer,(tmsize_t)m); - if (n==0) - return(0); - assert(n>0); - assert(n<=OJPEG_BUFFER); - assert(n<65536); - assert((uint64_t)n <= sp->in_buffer_file_togo); - m=(uint16_t)n; - sp->in_buffer_togo=m; - sp->in_buffer_cur=sp->in_buffer; - sp->in_buffer_file_togo-=m; - sp->in_buffer_file_pos+=m; - break; - } - sp->in_buffer_file_pos_log=0; - switch(sp->in_buffer_source) - { - case osibsNotSetYet: - if (sp->jpeg_interchange_format!=0) - { - sp->in_buffer_file_pos=sp->jpeg_interchange_format; - sp->in_buffer_file_togo=sp->jpeg_interchange_format_length; - } - sp->in_buffer_source=osibsJpegInterchangeFormat; - break; - case osibsJpegInterchangeFormat: - sp->in_buffer_source=osibsStrile; - break; - case osibsStrile: - if (sp->in_buffer_next_strile==sp->in_buffer_strile_count) - sp->in_buffer_source=osibsEof; - else - { - int err = 0; - sp->in_buffer_file_pos=TIFFGetStrileOffsetWithErr(sp->tif, sp->in_buffer_next_strile, &err); - if( err ) - return 0; - if (sp->in_buffer_file_pos!=0) - { - uint64_t bytecount = TIFFGetStrileByteCountWithErr(sp->tif, sp->in_buffer_next_strile, &err); - if( err ) - return 0; - if (sp->in_buffer_file_pos>=sp->file_size) - sp->in_buffer_file_pos=0; - else if (bytecount==0) - sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; - else - { - sp->in_buffer_file_togo=bytecount; - if (sp->in_buffer_file_togo==0) - sp->in_buffer_file_pos=0; - else if (sp->in_buffer_file_pos > UINT64_MAX - sp->in_buffer_file_togo || - sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size) - sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos; - } - } - sp->in_buffer_next_strile++; - } - break; - default: - return(0); - } - } while (1); - return(1); + } + sp->in_buffer_next_strile++; + } + break; + default: + return (0); + } + } while (1); + return (1); } -static int -OJPEGReadByte(OJPEGState* sp, uint8_t* byte) -{ - if (sp->in_buffer_togo==0) - { - if (OJPEGReadBufferFill(sp)==0) - return(0); - assert(sp->in_buffer_togo>0); - } - *byte=*(sp->in_buffer_cur); - sp->in_buffer_cur++; - sp->in_buffer_togo--; - return(1); +static int OJPEGReadByte(OJPEGState *sp, uint8_t *byte) +{ + if (sp->in_buffer_togo == 0) + { + if (OJPEGReadBufferFill(sp) == 0) + return (0); + assert(sp->in_buffer_togo > 0); + } + *byte = *(sp->in_buffer_cur); + sp->in_buffer_cur++; + sp->in_buffer_togo--; + return (1); } -static int -OJPEGReadBytePeek(OJPEGState* sp, uint8_t* byte) -{ - if (sp->in_buffer_togo==0) - { - if (OJPEGReadBufferFill(sp)==0) - return(0); - assert(sp->in_buffer_togo>0); - } - *byte=*(sp->in_buffer_cur); - return(1); +static int OJPEGReadBytePeek(OJPEGState *sp, uint8_t *byte) +{ + if (sp->in_buffer_togo == 0) + { + if (OJPEGReadBufferFill(sp) == 0) + return (0); + assert(sp->in_buffer_togo > 0); + } + *byte = *(sp->in_buffer_cur); + return (1); } -static void -OJPEGReadByteAdvance(OJPEGState* sp) +static void OJPEGReadByteAdvance(OJPEGState *sp) { - assert(sp->in_buffer_togo>0); - sp->in_buffer_cur++; - sp->in_buffer_togo--; + assert(sp->in_buffer_togo > 0); + sp->in_buffer_cur++; + sp->in_buffer_togo--; } -static int -OJPEGReadWord(OJPEGState* sp, uint16_t* word) -{ - uint8_t m; - if (OJPEGReadByte(sp,&m)==0) - return(0); - *word=(m<<8); - if (OJPEGReadByte(sp,&m)==0) - return(0); - *word|=m; - return(1); +static int OJPEGReadWord(OJPEGState *sp, uint16_t *word) +{ + uint8_t m; + if (OJPEGReadByte(sp, &m) == 0) + return (0); + *word = (m << 8); + if (OJPEGReadByte(sp, &m) == 0) + return (0); + *word |= m; + return (1); } -static int -OJPEGReadBlock(OJPEGState* sp, uint16_t len, void* mem) -{ - uint16_t mlen; - uint8_t* mmem; - uint16_t n; - assert(len>0); - mlen=len; - mmem=mem; - do - { - if (sp->in_buffer_togo==0) - { - if (OJPEGReadBufferFill(sp)==0) - return(0); - assert(sp->in_buffer_togo>0); - } - n=mlen; - if (n>sp->in_buffer_togo) - n=sp->in_buffer_togo; - _TIFFmemcpy(mmem,sp->in_buffer_cur,n); - sp->in_buffer_cur+=n; - sp->in_buffer_togo-=n; - mlen-=n; - mmem+=n; - } while(mlen>0); - return(1); +static int OJPEGReadBlock(OJPEGState *sp, uint16_t len, void *mem) +{ + uint16_t mlen; + uint8_t *mmem; + uint16_t n; + assert(len > 0); + mlen = len; + mmem = mem; + do + { + if (sp->in_buffer_togo == 0) + { + if (OJPEGReadBufferFill(sp) == 0) + return (0); + assert(sp->in_buffer_togo > 0); + } + n = mlen; + if (n > sp->in_buffer_togo) + n = sp->in_buffer_togo; + _TIFFmemcpy(mmem, sp->in_buffer_cur, n); + sp->in_buffer_cur += n; + sp->in_buffer_togo -= n; + mlen -= n; + mmem += n; + } while (mlen > 0); + return (1); } -static void -OJPEGReadSkip(OJPEGState* sp, uint16_t len) -{ - uint16_t m; - uint16_t n; - m=len; - n=m; - if (n>sp->in_buffer_togo) - n=sp->in_buffer_togo; - sp->in_buffer_cur+=n; - sp->in_buffer_togo-=n; - m-=n; - if (m>0) - { - assert(sp->in_buffer_togo==0); - n=m; - if ((uint64_t)n > sp->in_buffer_file_togo) - n=(uint16_t)sp->in_buffer_file_togo; - sp->in_buffer_file_pos+=n; - sp->in_buffer_file_togo-=n; - sp->in_buffer_file_pos_log=0; - /* we don't skip past jpeginterchangeformat/strile block... - * if that is asked from us, we're dealing with totally bazurk - * data anyway, and we've not seen this happening on any - * testfile, so we might as well likely cause some other - * meaningless error to be passed at some later time - */ - } +static void OJPEGReadSkip(OJPEGState *sp, uint16_t len) +{ + uint16_t m; + uint16_t n; + m = len; + n = m; + if (n > sp->in_buffer_togo) + n = sp->in_buffer_togo; + sp->in_buffer_cur += n; + sp->in_buffer_togo -= n; + m -= n; + if (m > 0) + { + assert(sp->in_buffer_togo == 0); + n = m; + if ((uint64_t)n > sp->in_buffer_file_togo) + n = (uint16_t)sp->in_buffer_file_togo; + sp->in_buffer_file_pos += n; + sp->in_buffer_file_togo -= n; + sp->in_buffer_file_pos_log = 0; + /* we don't skip past jpeginterchangeformat/strile block... + * if that is asked from us, we're dealing with totally bazurk + * data anyway, and we've not seen this happening on any + * testfile, so we might as well likely cause some other + * meaningless error to be passed at some later time + */ + } } -static int -OJPEGWriteStream(TIFF* tif, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - *len=0; - do - { - assert(sp->out_state<=ososEoi); - switch(sp->out_state) - { - case ososSoi: - OJPEGWriteStreamSoi(tif,mem,len); - break; - case ososQTable0: - OJPEGWriteStreamQTable(tif,0,mem,len); - break; - case ososQTable1: - OJPEGWriteStreamQTable(tif,1,mem,len); - break; - case ososQTable2: - OJPEGWriteStreamQTable(tif,2,mem,len); - break; - case ososQTable3: - OJPEGWriteStreamQTable(tif,3,mem,len); - break; - case ososDcTable0: - OJPEGWriteStreamDcTable(tif,0,mem,len); - break; - case ososDcTable1: - OJPEGWriteStreamDcTable(tif,1,mem,len); - break; - case ososDcTable2: - OJPEGWriteStreamDcTable(tif,2,mem,len); - break; - case ososDcTable3: - OJPEGWriteStreamDcTable(tif,3,mem,len); - break; - case ososAcTable0: - OJPEGWriteStreamAcTable(tif,0,mem,len); - break; - case ososAcTable1: - OJPEGWriteStreamAcTable(tif,1,mem,len); - break; - case ososAcTable2: - OJPEGWriteStreamAcTable(tif,2,mem,len); - break; - case ososAcTable3: - OJPEGWriteStreamAcTable(tif,3,mem,len); - break; - case ososDri: - OJPEGWriteStreamDri(tif,mem,len); - break; - case ososSof: - OJPEGWriteStreamSof(tif,mem,len); - break; - case ososSos: - OJPEGWriteStreamSos(tif,mem,len); - break; - case ososCompressed: - if (OJPEGWriteStreamCompressed(tif,mem,len)==0) - return(0); - break; - case ososRst: - OJPEGWriteStreamRst(tif,mem,len); - break; - case ososEoi: - OJPEGWriteStreamEoi(tif,mem,len); - break; - } - } while (*len==0); - return(1); +static int OJPEGWriteStream(TIFF *tif, void **mem, uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + *len = 0; + do + { + assert(sp->out_state <= ososEoi); + switch (sp->out_state) + { + case ososSoi: + OJPEGWriteStreamSoi(tif, mem, len); + break; + case ososQTable0: + OJPEGWriteStreamQTable(tif, 0, mem, len); + break; + case ososQTable1: + OJPEGWriteStreamQTable(tif, 1, mem, len); + break; + case ososQTable2: + OJPEGWriteStreamQTable(tif, 2, mem, len); + break; + case ososQTable3: + OJPEGWriteStreamQTable(tif, 3, mem, len); + break; + case ososDcTable0: + OJPEGWriteStreamDcTable(tif, 0, mem, len); + break; + case ososDcTable1: + OJPEGWriteStreamDcTable(tif, 1, mem, len); + break; + case ososDcTable2: + OJPEGWriteStreamDcTable(tif, 2, mem, len); + break; + case ososDcTable3: + OJPEGWriteStreamDcTable(tif, 3, mem, len); + break; + case ososAcTable0: + OJPEGWriteStreamAcTable(tif, 0, mem, len); + break; + case ososAcTable1: + OJPEGWriteStreamAcTable(tif, 1, mem, len); + break; + case ososAcTable2: + OJPEGWriteStreamAcTable(tif, 2, mem, len); + break; + case ososAcTable3: + OJPEGWriteStreamAcTable(tif, 3, mem, len); + break; + case ososDri: + OJPEGWriteStreamDri(tif, mem, len); + break; + case ososSof: + OJPEGWriteStreamSof(tif, mem, len); + break; + case ososSos: + OJPEGWriteStreamSos(tif, mem, len); + break; + case ososCompressed: + if (OJPEGWriteStreamCompressed(tif, mem, len) == 0) + return (0); + break; + case ososRst: + OJPEGWriteStreamRst(tif, mem, len); + break; + case ososEoi: + OJPEGWriteStreamEoi(tif, mem, len); + break; + } + } while (*len == 0); + return (1); } -static void -OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(OJPEG_BUFFER>=2); - sp->out_buffer[0]=255; - sp->out_buffer[1]=JPEG_MARKER_SOI; - *len=2; - *mem=(void*)sp->out_buffer; - sp->out_state++; +static void OJPEGWriteStreamSoi(TIFF *tif, void **mem, uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(OJPEG_BUFFER >= 2); + sp->out_buffer[0] = 255; + sp->out_buffer[1] = JPEG_MARKER_SOI; + *len = 2; + *mem = (void *)sp->out_buffer; + sp->out_state++; } -static void -OJPEGWriteStreamQTable(TIFF* tif, uint8_t table_index, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - if (sp->qtable[table_index]!=0) - { - *mem=(void*)(sp->qtable[table_index]+sizeof(uint32_t)); - *len= *((uint32_t*)sp->qtable[table_index]) - sizeof(uint32_t); - } - sp->out_state++; +static void OJPEGWriteStreamQTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + if (sp->qtable[table_index] != 0) + { + *mem = (void *)(sp->qtable[table_index] + sizeof(uint32_t)); + *len = *((uint32_t *)sp->qtable[table_index]) - sizeof(uint32_t); + } + sp->out_state++; } -static void -OJPEGWriteStreamDcTable(TIFF* tif, uint8_t table_index, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - if (sp->dctable[table_index]!=0) - { - *mem=(void*)(sp->dctable[table_index]+sizeof(uint32_t)); - *len= *((uint32_t*)sp->dctable[table_index]) - sizeof(uint32_t); - } - sp->out_state++; +static void OJPEGWriteStreamDcTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + if (sp->dctable[table_index] != 0) + { + *mem = (void *)(sp->dctable[table_index] + sizeof(uint32_t)); + *len = *((uint32_t *)sp->dctable[table_index]) - sizeof(uint32_t); + } + sp->out_state++; } -static void -OJPEGWriteStreamAcTable(TIFF* tif, uint8_t table_index, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - if (sp->actable[table_index]!=0) - { - *mem=(void*)(sp->actable[table_index]+sizeof(uint32_t)); - *len= *((uint32_t*)sp->actable[table_index]) - sizeof(uint32_t); - } - sp->out_state++; +static void OJPEGWriteStreamAcTable(TIFF *tif, uint8_t table_index, void **mem, + uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + if (sp->actable[table_index] != 0) + { + *mem = (void *)(sp->actable[table_index] + sizeof(uint32_t)); + *len = *((uint32_t *)sp->actable[table_index]) - sizeof(uint32_t); + } + sp->out_state++; } -static void -OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(OJPEG_BUFFER>=6); - if (sp->restart_interval!=0) - { - sp->out_buffer[0]=255; - sp->out_buffer[1]=JPEG_MARKER_DRI; - sp->out_buffer[2]=0; - sp->out_buffer[3]=4; - sp->out_buffer[4]=(sp->restart_interval>>8); - sp->out_buffer[5]=(sp->restart_interval&255); - *len=6; - *mem=(void*)sp->out_buffer; - } - sp->out_state++; +static void OJPEGWriteStreamDri(TIFF *tif, void **mem, uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(OJPEG_BUFFER >= 6); + if (sp->restart_interval != 0) + { + sp->out_buffer[0] = 255; + sp->out_buffer[1] = JPEG_MARKER_DRI; + sp->out_buffer[2] = 0; + sp->out_buffer[3] = 4; + sp->out_buffer[4] = (sp->restart_interval >> 8); + sp->out_buffer[5] = (sp->restart_interval & 255); + *len = 6; + *mem = (void *)sp->out_buffer; + } + sp->out_state++; } -static void -OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t m; - assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3); - assert(255>=8+sp->samples_per_pixel_per_plane*3); - sp->out_buffer[0]=255; - sp->out_buffer[1]=sp->sof_marker_id; - /* Lf */ - sp->out_buffer[2]=0; - sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3; - /* P */ - sp->out_buffer[4]=8; - /* Y */ - sp->out_buffer[5]=(uint8_t)(sp->sof_y >> 8); - sp->out_buffer[6]=(sp->sof_y&255); - /* X */ - sp->out_buffer[7]=(uint8_t)(sp->sof_x >> 8); - sp->out_buffer[8]=(sp->sof_x&255); - /* Nf */ - sp->out_buffer[9]=sp->samples_per_pixel_per_plane; - for (m=0; m<sp->samples_per_pixel_per_plane; m++) - { - /* C */ - sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m]; - /* H and V */ - sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m]; - /* Tq */ - sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m]; - } - *len=10+sp->samples_per_pixel_per_plane*3; - *mem=(void*)sp->out_buffer; - sp->out_state++; +static void OJPEGWriteStreamSof(TIFF *tif, void **mem, uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + assert(OJPEG_BUFFER >= 2 + 8 + sp->samples_per_pixel_per_plane * 3); + assert(255 >= 8 + sp->samples_per_pixel_per_plane * 3); + sp->out_buffer[0] = 255; + sp->out_buffer[1] = sp->sof_marker_id; + /* Lf */ + sp->out_buffer[2] = 0; + sp->out_buffer[3] = 8 + sp->samples_per_pixel_per_plane * 3; + /* P */ + sp->out_buffer[4] = 8; + /* Y */ + sp->out_buffer[5] = (uint8_t)(sp->sof_y >> 8); + sp->out_buffer[6] = (sp->sof_y & 255); + /* X */ + sp->out_buffer[7] = (uint8_t)(sp->sof_x >> 8); + sp->out_buffer[8] = (sp->sof_x & 255); + /* Nf */ + sp->out_buffer[9] = sp->samples_per_pixel_per_plane; + for (m = 0; m < sp->samples_per_pixel_per_plane; m++) + { + /* C */ + sp->out_buffer[10 + m * 3] = sp->sof_c[sp->plane_sample_offset + m]; + /* H and V */ + sp->out_buffer[10 + m * 3 + 1] = + sp->sof_hv[sp->plane_sample_offset + m]; + /* Tq */ + sp->out_buffer[10 + m * 3 + 2] = + sp->sof_tq[sp->plane_sample_offset + m]; + } + *len = 10 + sp->samples_per_pixel_per_plane * 3; + *mem = (void *)sp->out_buffer; + sp->out_state++; } -static void -OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - uint8_t m; - assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2); - assert(255>=6+sp->samples_per_pixel_per_plane*2); - sp->out_buffer[0]=255; - sp->out_buffer[1]=JPEG_MARKER_SOS; - /* Ls */ - sp->out_buffer[2]=0; - sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2; - /* Ns */ - sp->out_buffer[4]=sp->samples_per_pixel_per_plane; - for (m=0; m<sp->samples_per_pixel_per_plane; m++) - { - /* Cs */ - sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m]; - /* Td and Ta */ - sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m]; - } - /* Ss */ - sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0; - /* Se */ - sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63; - /* Ah and Al */ - sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0; - *len=8+sp->samples_per_pixel_per_plane*2; - *mem=(void*)sp->out_buffer; - sp->out_state++; +static void OJPEGWriteStreamSos(TIFF *tif, void **mem, uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + uint8_t m; + assert(OJPEG_BUFFER >= 2 + 6 + sp->samples_per_pixel_per_plane * 2); + assert(255 >= 6 + sp->samples_per_pixel_per_plane * 2); + sp->out_buffer[0] = 255; + sp->out_buffer[1] = JPEG_MARKER_SOS; + /* Ls */ + sp->out_buffer[2] = 0; + sp->out_buffer[3] = 6 + sp->samples_per_pixel_per_plane * 2; + /* Ns */ + sp->out_buffer[4] = sp->samples_per_pixel_per_plane; + for (m = 0; m < sp->samples_per_pixel_per_plane; m++) + { + /* Cs */ + sp->out_buffer[5 + m * 2] = sp->sos_cs[sp->plane_sample_offset + m]; + /* Td and Ta */ + sp->out_buffer[5 + m * 2 + 1] = + sp->sos_tda[sp->plane_sample_offset + m]; + } + /* Ss */ + sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2] = 0; + /* Se */ + sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 1] = 63; + /* Ah and Al */ + sp->out_buffer[5 + sp->samples_per_pixel_per_plane * 2 + 2] = 0; + *len = 8 + sp->samples_per_pixel_per_plane * 2; + *mem = (void *)sp->out_buffer; + sp->out_state++; } -static int -OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - if (sp->in_buffer_togo==0) - { - if (OJPEGReadBufferFill(sp)==0) - return(0); - assert(sp->in_buffer_togo>0); - } - *len=sp->in_buffer_togo; - *mem=(void*)sp->in_buffer_cur; - sp->in_buffer_togo=0; - if (sp->in_buffer_file_togo==0) - { - switch(sp->in_buffer_source) - { - case osibsStrile: - if (sp->in_buffer_next_strile<sp->in_buffer_strile_count) - sp->out_state=ososRst; - else - sp->out_state=ososEoi; - break; - case osibsEof: - sp->out_state=ososEoi; - break; - default: - break; - } - } - return(1); +static int OJPEGWriteStreamCompressed(TIFF *tif, void **mem, uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + if (sp->in_buffer_togo == 0) + { + if (OJPEGReadBufferFill(sp) == 0) + return (0); + assert(sp->in_buffer_togo > 0); + } + *len = sp->in_buffer_togo; + *mem = (void *)sp->in_buffer_cur; + sp->in_buffer_togo = 0; + if (sp->in_buffer_file_togo == 0) + { + switch (sp->in_buffer_source) + { + case osibsStrile: + if (sp->in_buffer_next_strile < sp->in_buffer_strile_count) + sp->out_state = ososRst; + else + sp->out_state = ososEoi; + break; + case osibsEof: + sp->out_state = ososEoi; + break; + default: + break; + } + } + return (1); } -static void -OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(OJPEG_BUFFER>=2); - sp->out_buffer[0]=255; - sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index; - sp->restart_index++; - if (sp->restart_index==8) - sp->restart_index=0; - *len=2; - *mem=(void*)sp->out_buffer; - sp->out_state=ososCompressed; +static void OJPEGWriteStreamRst(TIFF *tif, void **mem, uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(OJPEG_BUFFER >= 2); + sp->out_buffer[0] = 255; + sp->out_buffer[1] = JPEG_MARKER_RST0 + sp->restart_index; + sp->restart_index++; + if (sp->restart_index == 8) + sp->restart_index = 0; + *len = 2; + *mem = (void *)sp->out_buffer; + sp->out_state = ososCompressed; } -static void -OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32_t* len) -{ - OJPEGState* sp=(OJPEGState*)tif->tif_data; - assert(OJPEG_BUFFER>=2); - sp->out_buffer[0]=255; - sp->out_buffer[1]=JPEG_MARKER_EOI; - *len=2; - *mem=(void*)sp->out_buffer; +static void OJPEGWriteStreamEoi(TIFF *tif, void **mem, uint32_t *len) +{ + OJPEGState *sp = (OJPEGState *)tif->tif_data; + assert(OJPEG_BUFFER >= 2); + sp->out_buffer[0] = 255; + sp->out_buffer[1] = JPEG_MARKER_EOI; + *len = 2; + *mem = (void *)sp->out_buffer; } #ifndef LIBJPEG_ENCAP_EXTERNAL -static int -jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo) -{ - if( SETJMP(sp->exit_jmpbuf) ) - return 0; - else { - jpeg_create_decompress(cinfo); - return 1; - } +static int jpeg_create_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo) +{ + if (SETJMP(sp->exit_jmpbuf)) + return 0; + else + { + jpeg_create_decompress(cinfo); + return 1; + } } #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static int -jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8_t require_image) -{ - if( SETJMP(sp->exit_jmpbuf) ) - return 0; - else { - jpeg_read_header(cinfo,require_image); - return 1; - } +static int jpeg_read_header_encap(OJPEGState *sp, jpeg_decompress_struct *cinfo, + uint8_t require_image) +{ + if (SETJMP(sp->exit_jmpbuf)) + return 0; + else + { + jpeg_read_header(cinfo, require_image); + return 1; + } } #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static int -jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo) -{ - if( SETJMP(sp->exit_jmpbuf) ) - return 0; - else { - jpeg_start_decompress(cinfo); - return 1; - } +static int jpeg_start_decompress_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo) +{ + if (SETJMP(sp->exit_jmpbuf)) + return 0; + else + { + jpeg_start_decompress(cinfo); + return 1; + } } #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static int -jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32_t max_lines) -{ - if( SETJMP(sp->exit_jmpbuf) ) - return 0; - else { - jpeg_read_scanlines(cinfo,scanlines,max_lines); - return 1; - } +static int jpeg_read_scanlines_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, + void *scanlines, uint32_t max_lines) +{ + if (SETJMP(sp->exit_jmpbuf)) + return 0; + else + { + jpeg_read_scanlines(cinfo, scanlines, max_lines); + return 1; + } } #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static int -jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32_t max_lines) -{ - if( SETJMP(sp->exit_jmpbuf) ) - return 0; - else { - jpeg_read_raw_data(cinfo,data,max_lines); - return 1; - } +static int jpeg_read_raw_data_encap(OJPEGState *sp, + jpeg_decompress_struct *cinfo, void *data, + uint32_t max_lines) +{ + if (SETJMP(sp->exit_jmpbuf)) + return 0; + else + { + jpeg_read_raw_data(cinfo, data, max_lines); + return 1; + } } #endif #ifndef LIBJPEG_ENCAP_EXTERNAL -static void -jpeg_encap_unwind(TIFF* tif) +static void jpeg_encap_unwind(TIFF *tif) { - OJPEGState* sp=(OJPEGState*)tif->tif_data; - LONGJMP(sp->exit_jmpbuf,1); + OJPEGState *sp = (OJPEGState *)tif->tif_data; + LONGJMP(sp->exit_jmpbuf, 1); } #endif -static void -OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo) +static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct *cinfo) { - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo,buffer); - TIFFWarningExtR(((TIFF*)(cinfo->client_data)),"LibJpeg","%s",buffer); + char buffer[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message)(cinfo, buffer); + TIFFWarningExtR(((TIFF *)(cinfo->client_data)), "LibJpeg", "%s", buffer); } -static void -OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo) +static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct *cinfo) { - char buffer[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message)(cinfo,buffer); - TIFFErrorExtR(((TIFF*)(cinfo->client_data)),"LibJpeg","%s",buffer); - jpeg_encap_unwind((TIFF*)(cinfo->client_data)); + char buffer[JMSG_LENGTH_MAX]; + (*cinfo->err->format_message)(cinfo, buffer); + TIFFErrorExtR(((TIFF *)(cinfo->client_data)), "LibJpeg", "%s", buffer); + jpeg_encap_unwind((TIFF *)(cinfo->client_data)); } -static void -OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo) +static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct *cinfo) { - (void)cinfo; + (void)cinfo; } static boolean -OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo) -{ - TIFF* tif=(TIFF*)cinfo->client_data; - OJPEGState* sp=(OJPEGState*)tif->tif_data; - void* mem=0; - uint32_t len=0U; - if (OJPEGWriteStream(tif,&mem,&len)==0) - { - TIFFErrorExtR(tif,"LibJpeg","Premature end of JPEG data"); - jpeg_encap_unwind(tif); - } - sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=len; - sp->libjpeg_jpeg_source_mgr.next_input_byte=mem; - return(1); +OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct *cinfo) +{ + TIFF *tif = (TIFF *)cinfo->client_data; + OJPEGState *sp = (OJPEGState *)tif->tif_data; + void *mem = 0; + uint32_t len = 0U; + if (OJPEGWriteStream(tif, &mem, &len) == 0) + { + TIFFErrorExtR(tif, "LibJpeg", "Premature end of JPEG data"); + jpeg_encap_unwind(tif); + } + sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = len; + sp->libjpeg_jpeg_source_mgr.next_input_byte = mem; + return (1); } static void -OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes) +OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct *cinfo, + long num_bytes) { - TIFF* tif=(TIFF*)cinfo->client_data; - (void)num_bytes; - TIFFErrorExtR(tif,"LibJpeg","Unexpected error"); - jpeg_encap_unwind(tif); + TIFF *tif = (TIFF *)cinfo->client_data; + (void)num_bytes; + TIFFErrorExtR(tif, "LibJpeg", "Unexpected error"); + jpeg_encap_unwind(tif); } #ifdef _MSC_VER -#pragma warning( push ) -#pragma warning( disable : 4702 ) /* unreachable code */ +#pragma warning(push) +#pragma warning(disable : 4702) /* unreachable code */ #endif static boolean -OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired) +OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct *cinfo, + int desired) { - TIFF* tif=(TIFF*)cinfo->client_data; - (void)desired; - TIFFErrorExtR(tif,"LibJpeg","Unexpected error"); - jpeg_encap_unwind(tif); - return(0); + TIFF *tif = (TIFF *)cinfo->client_data; + (void)desired; + TIFFErrorExtR(tif, "LibJpeg", "Unexpected error"); + jpeg_encap_unwind(tif); + return (0); } #ifdef _MSC_VER -#pragma warning( pop ) +#pragma warning(pop) #endif -static void -OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo) +static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct *cinfo) { - (void)cinfo; + (void)cinfo; } #endif diff --git a/libtiff/tif_open.c b/libtiff/tif_open.c index 787e83d3..1b80ba73 100644 --- a/libtiff/tif_open.c +++ b/libtiff/tif_open.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -30,87 +30,97 @@ /* * Dummy functions to fill the omitted client procedures. */ -static int -_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) +static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize) { - (void) fd; (void) pbase; (void) psize; - return (0); + (void)fd; + (void)pbase; + (void)psize; + return (0); } -static void -_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) +static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size) { - (void) fd; (void) base; (void) size; + (void)fd; + (void)base; + (void)size; } -int -_TIFFgetMode(TIFFOpenOptions* opts, thandle_t clientdata, const char* mode, const char* module) +int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode, + const char *module) { - int m = -1; - - switch (mode[0]) { - case 'r': - m = O_RDONLY; - if (mode[1] == '+') - m = O_RDWR; - break; - case 'w': - case 'a': - m = O_RDWR|O_CREAT; - if (mode[0] == 'w') - m |= O_TRUNC; - break; - default: - _TIFFErrorEarly(opts, clientdata, module, "\"%s\": Bad mode", mode); - break; - } - return (m); + int m = -1; + + switch (mode[0]) + { + case 'r': + m = O_RDONLY; + if (mode[1] == '+') + m = O_RDWR; + break; + case 'w': + case 'a': + m = O_RDWR | O_CREAT; + if (mode[0] == 'w') + m |= O_TRUNC; + break; + default: + _TIFFErrorEarly(opts, clientdata, module, "\"%s\": Bad mode", mode); + break; + } + return (m); } -TIFFOpenOptions* TIFFOpenOptionsAlloc() +TIFFOpenOptions *TIFFOpenOptionsAlloc() { - TIFFOpenOptions* opts = (TIFFOpenOptions*)_TIFFcalloc(1, sizeof(TIFFOpenOptions)); + TIFFOpenOptions *opts = + (TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions)); return opts; } -void TIFFOpenOptionsFree(TIFFOpenOptions* opts) -{ - _TIFFfree(opts); -} +void TIFFOpenOptionsFree(TIFFOpenOptions *opts) { _TIFFfree(opts); } /** Define a limit in bytes for a single memory allocation done by libtiff. * If max_single_mem_alloc is set to 0, no other limit that the underlying * _TIFFmalloc() will be applied, which is the default. */ -void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions* opts, tmsize_t max_single_mem_alloc) +void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts, + tmsize_t max_single_mem_alloc) { opts->max_single_mem_alloc = max_single_mem_alloc; } -void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions* opts, TIFFErrorHandlerExtR handler, void* errorhandler_user_data) +void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts, + TIFFErrorHandlerExtR handler, + void *errorhandler_user_data) { opts->errorhandler = handler; opts->errorhandler_user_data = errorhandler_user_data; } -void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions* opts, TIFFErrorHandlerExtR handler, void* warnhandler_user_data) +void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts, + TIFFErrorHandlerExtR handler, + void *warnhandler_user_data) { opts->warnhandler = handler; opts->warnhandler_user_data = warnhandler_user_data; } -static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF* tif, const char* pszFunction, tmsize_t s) +static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF *tif, + const char *pszFunction, + tmsize_t s) { TIFFErrorExtR(tif, pszFunction, - "Memory allocation of %" PRIu64 " bytes is beyond the %" PRIu64 " byte limit defined in open options", - (uint64_t)s, - (uint64_t)tif->tif_max_single_mem_alloc); + "Memory allocation of %" PRIu64 + " bytes is beyond the %" PRIu64 + " byte limit defined in open options", + (uint64_t)s, (uint64_t)tif->tif_max_single_mem_alloc); } /** malloc() version that takes into account memory-specific open options */ -void* _TIFFmallocExt(TIFF* tif, tmsize_t s) +void *_TIFFmallocExt(TIFF *tif, tmsize_t s) { - if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && s > tif->tif_max_single_mem_alloc) + if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && + s > tif->tif_max_single_mem_alloc) { _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFmallocExt", s); return NULL; @@ -119,7 +129,7 @@ void* _TIFFmallocExt(TIFF* tif, tmsize_t s) } /** calloc() version that takes into account memory-specific open options */ -void* _TIFFcallocExt(TIFF* tif, tmsize_t nmemb, tmsize_t siz) +void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz) { if (tif != NULL && tif->tif_max_single_mem_alloc > 0) { @@ -127,7 +137,8 @@ void* _TIFFcallocExt(TIFF* tif, tmsize_t nmemb, tmsize_t siz) return NULL; if (nmemb * siz > tif->tif_max_single_mem_alloc) { - _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt", nmemb * siz); + _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt", + nmemb * siz); return NULL; } } @@ -135,9 +146,10 @@ void* _TIFFcallocExt(TIFF* tif, tmsize_t nmemb, tmsize_t siz) } /** realloc() version that takes into account memory-specific open options */ -void* _TIFFreallocExt(TIFF* tif, void* p, tmsize_t s) +void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s) { - if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && s > tif->tif_max_single_mem_alloc) + if (tif != NULL && tif->tif_max_single_mem_alloc > 0 && + s > tif->tif_max_single_mem_alloc) { _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFreallocExt", s); return NULL; @@ -146,113 +158,102 @@ void* _TIFFreallocExt(TIFF* tif, void* p, tmsize_t s) } /** free() version that takes into account memory-specific open options */ -void _TIFFfreeExt(TIFF* tif, void* p) +void _TIFFfreeExt(TIFF *tif, void *p) { (void)tif; _TIFFfree(p); } +TIFF *TIFFClientOpen(const char *name, const char *mode, thandle_t clientdata, + TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, + TIFFSeekProc seekproc, TIFFCloseProc closeproc, + TIFFSizeProc sizeproc, TIFFMapFileProc mapproc, + TIFFUnmapFileProc unmapproc) +{ + return TIFFClientOpenExt(name, mode, clientdata, readproc, writeproc, + seekproc, closeproc, sizeproc, mapproc, unmapproc, + NULL); +} + +TIFF *TIFFClientOpenExt(const char *name, const char *mode, + thandle_t clientdata, TIFFReadWriteProc readproc, + TIFFReadWriteProc writeproc, TIFFSeekProc seekproc, + TIFFCloseProc closeproc, TIFFSizeProc sizeproc, + TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc, + TIFFOpenOptions *opts) +{ + static const char module[] = "TIFFClientOpenExt"; + TIFF *tif; + int m; + const char *cp; + + /* The following are configuration checks. They should be redundant, but + * should not compile to any actual code in an optimised release build + * anyway. If any of them fail, (makefile-based or other) configuration is + * not correct */ + assert(sizeof(uint8_t) == 1); + assert(sizeof(int8_t) == 1); + assert(sizeof(uint16_t) == 2); + assert(sizeof(int16_t) == 2); + assert(sizeof(uint32_t) == 4); + assert(sizeof(int32_t) == 4); + assert(sizeof(uint64_t) == 8); + assert(sizeof(int64_t) == 8); + { + union + { + uint8_t a8[2]; + uint16_t a16; + } n; + n.a8[0] = 1; + n.a8[1] = 0; + (void)n; +#ifdef WORDS_BIGENDIAN + assert(n.a16 == 256); +#else + assert(n.a16 == 1); +#endif + } -TIFF* -TIFFClientOpen( - const char* name, const char* mode, - thandle_t clientdata, - TIFFReadWriteProc readproc, - TIFFReadWriteProc writeproc, - TIFFSeekProc seekproc, - TIFFCloseProc closeproc, - TIFFSizeProc sizeproc, - TIFFMapFileProc mapproc, - TIFFUnmapFileProc unmapproc -) { - return TIFFClientOpenExt(name, mode, clientdata, - readproc, - writeproc, - seekproc, - closeproc, - sizeproc, - mapproc, - unmapproc, - NULL); -} - -TIFF* -TIFFClientOpenExt( - const char* name, const char* mode, - thandle_t clientdata, - TIFFReadWriteProc readproc, - TIFFReadWriteProc writeproc, - TIFFSeekProc seekproc, - TIFFCloseProc closeproc, - TIFFSizeProc sizeproc, - TIFFMapFileProc mapproc, - TIFFUnmapFileProc unmapproc, - TIFFOpenOptions* opts) -{ - static const char module[] = "TIFFClientOpenExt"; - TIFF *tif; - int m; - const char* cp; - - /* The following are configuration checks. They should be redundant, but should not - * compile to any actual code in an optimised release build anyway. If any of them - * fail, (makefile-based or other) configuration is not correct */ - assert(sizeof(uint8_t) == 1); - assert(sizeof(int8_t) == 1); - assert(sizeof(uint16_t) == 2); - assert(sizeof(int16_t) == 2); - assert(sizeof(uint32_t) == 4); - assert(sizeof(int32_t) == 4); - assert(sizeof(uint64_t) == 8); - assert(sizeof(int64_t) == 8); - { - union{ - uint8_t a8[2]; - uint16_t a16; - } n; - n.a8[0]=1; - n.a8[1]=0; - (void)n; - #ifdef WORDS_BIGENDIAN - assert(n.a16==256); - #else - assert(n.a16==1); - #endif - } - - m = _TIFFgetMode(opts, clientdata, mode, module); - if (m == -1) - goto bad2; - tmsize_t size_to_alloc = (tmsize_t)(sizeof (TIFF) + strlen(name) + 1); - if (opts && opts->max_single_mem_alloc > 0 && - size_to_alloc > opts->max_single_mem_alloc) { - _TIFFErrorEarly(opts, clientdata, module, - "%s: Memory allocation of %" PRIu64 " bytes is beyond the %" PRIu64 " byte limit defined in open options", - name, (uint64_t)size_to_alloc, (uint64_t)opts->max_single_mem_alloc); - goto bad2; - } - tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc); - if (tif == NULL) { - _TIFFErrorEarly(opts, clientdata, module, "%s: Out of memory (TIFF structure)", name); - goto bad2; - } - _TIFFmemset(tif, 0, sizeof (*tif)); - tif->tif_name = (char *)tif + sizeof (TIFF); - strcpy(tif->tif_name, name); - tif->tif_mode = m &~ (O_CREAT|O_TRUNC); - tif->tif_curdir = (uint16_t) -1; /* non-existent directory */ - tif->tif_curoff = 0; - tif->tif_curstrip = (uint32_t) -1; /* invalid strip */ - tif->tif_row = (uint32_t) -1; /* read/write pre-increment */ - tif->tif_clientdata = clientdata; - tif->tif_readproc = readproc; - tif->tif_writeproc = writeproc; - tif->tif_seekproc = seekproc; - tif->tif_closeproc = closeproc; - tif->tif_sizeproc = sizeproc; - tif->tif_mapproc = mapproc ? mapproc : _tiffDummyMapProc; - tif->tif_unmapproc = unmapproc ? unmapproc : _tiffDummyUnmapProc; - if( opts ) + m = _TIFFgetMode(opts, clientdata, mode, module); + if (m == -1) + goto bad2; + tmsize_t size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1); + if (opts && opts->max_single_mem_alloc > 0 && + size_to_alloc > opts->max_single_mem_alloc) + { + _TIFFErrorEarly(opts, clientdata, module, + "%s: Memory allocation of %" PRIu64 + " bytes is beyond the %" PRIu64 + " byte limit defined in open options", + name, (uint64_t)size_to_alloc, + (uint64_t)opts->max_single_mem_alloc); + goto bad2; + } + tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc); + if (tif == NULL) + { + _TIFFErrorEarly(opts, clientdata, module, + "%s: Out of memory (TIFF structure)", name); + goto bad2; + } + _TIFFmemset(tif, 0, sizeof(*tif)); + tif->tif_name = (char *)tif + sizeof(TIFF); + strcpy(tif->tif_name, name); + tif->tif_mode = m & ~(O_CREAT | O_TRUNC); + tif->tif_curdir = (uint16_t)-1; /* non-existent directory */ + tif->tif_curoff = 0; + tif->tif_curstrip = (uint32_t)-1; /* invalid strip */ + tif->tif_row = (uint32_t)-1; /* read/write pre-increment */ + tif->tif_clientdata = clientdata; + tif->tif_readproc = readproc; + tif->tif_writeproc = writeproc; + tif->tif_seekproc = seekproc; + tif->tif_closeproc = closeproc; + tif->tif_sizeproc = sizeproc; + tif->tif_mapproc = mapproc ? mapproc : _tiffDummyMapProc; + tif->tif_unmapproc = unmapproc ? unmapproc : _tiffDummyUnmapProc; + if (opts) { tif->tif_errorhandler = opts->errorhandler; tif->tif_errorhandler_user_data = opts->errorhandler_user_data; @@ -261,366 +262,388 @@ TIFFClientOpenExt( tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc; } - if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) { - TIFFErrorExtR(tif, module, - "One of the client procedures is NULL pointer."); - _TIFFfreeExt(NULL, tif); - goto bad2; - } - - _TIFFSetDefaultCompressionState(tif); /* setup default state */ - /* - * Default is to return data MSB2LSB and enable the - * use of memory-mapped files and strip chopping when - * a file is opened read-only. - */ - tif->tif_flags = FILLORDER_MSB2LSB; - if (m == O_RDONLY ) - tif->tif_flags |= TIFF_MAPPED; - - #ifdef STRIPCHOP_DEFAULT - if (m == O_RDONLY || m == O_RDWR) - tif->tif_flags |= STRIPCHOP_DEFAULT; - #endif - - /* - * Process library-specific flags in the open mode string. - * The following flags may be used to control intrinsic library - * behavior that may or may not be desirable (usually for - * compatibility with some application that claims to support - * TIFF but only supports some brain dead idea of what the - * vendor thinks TIFF is): - * - * 'l' use little-endian byte order for creating a file - * 'b' use big-endian byte order for creating a file - * 'L' read/write information using LSB2MSB bit order - * 'B' read/write information using MSB2LSB bit order - * 'H' read/write information using host bit order - * 'M' enable use of memory-mapped files when supported - * 'm' disable use of memory-mapped files - * 'C' enable strip chopping support when reading - * 'c' disable strip chopping support - * 'h' read TIFF header only, do not load the first IFD - * '4' ClassicTIFF for creating a file (default) - * '8' BigTIFF for creating a file - * 'D' enable use of deferred strip/tile offset/bytecount array loading. - * 'O' on-demand loading of values instead of whole array loading (implies D) - * - * The use of the 'l' and 'b' flags is strongly discouraged. - * These flags are provided solely because numerous vendors, - * typically on the PC, do not correctly support TIFF; they - * only support the Intel little-endian byte order. This - * support is not configured by default because it supports - * the violation of the TIFF spec that says that readers *MUST* - * support both byte orders. It is strongly recommended that - * you not use this feature except to deal with busted apps - * that write invalid TIFF. And even in those cases you should - * bang on the vendors to fix their software. - * - * The 'L', 'B', and 'H' flags are intended for applications - * that can optimize operations on data by using a particular - * bit order. By default the library returns data in MSB2LSB - * bit order for compatibility with older versions of this - * library. Returning data in the bit order of the native CPU - * makes the most sense but also requires applications to check - * the value of the FillOrder tag; something they probably do - * not do right now. - * - * The 'M' and 'm' flags are provided because some virtual memory - * systems exhibit poor behavior when large images are mapped. - * These options permit clients to control the use of memory-mapped - * files on a per-file basis. - * - * The 'C' and 'c' flags are provided because the library support - * for chopping up large strips into multiple smaller strips is not - * application-transparent and as such can cause problems. The 'c' - * option permits applications that only want to look at the tags, - * for example, to get the unadulterated TIFF tag information. - */ - for (cp = mode; *cp; cp++) - switch (*cp) { - case 'b': - #ifndef WORDS_BIGENDIAN - if (m&O_CREAT) - tif->tif_flags |= TIFF_SWAB; - #endif - break; - case 'l': - #ifdef WORDS_BIGENDIAN - if ((m&O_CREAT)) - tif->tif_flags |= TIFF_SWAB; - #endif - break; - case 'B': - tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | - FILLORDER_MSB2LSB; - break; - case 'L': - tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | - FILLORDER_LSB2MSB; - break; - case 'H': - tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | - HOST_FILLORDER; - break; - case 'M': - if (m == O_RDONLY) - tif->tif_flags |= TIFF_MAPPED; - break; - case 'm': - if (m == O_RDONLY) - tif->tif_flags &= ~TIFF_MAPPED; - break; - case 'C': - if (m == O_RDONLY) - tif->tif_flags |= TIFF_STRIPCHOP; - break; - case 'c': - if (m == O_RDONLY) - tif->tif_flags &= ~TIFF_STRIPCHOP; - break; - case 'h': - tif->tif_flags |= TIFF_HEADERONLY; - break; - case '8': - if (m&O_CREAT) - tif->tif_flags |= TIFF_BIGTIFF; - break; - case 'D': - tif->tif_flags |= TIFF_DEFERSTRILELOAD; - break; - case 'O': - if( m == O_RDONLY ) - tif->tif_flags |= (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD); - break; - } + if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) + { + TIFFErrorExtR(tif, module, + "One of the client procedures is NULL pointer."); + _TIFFfreeExt(NULL, tif); + goto bad2; + } + + _TIFFSetDefaultCompressionState(tif); /* setup default state */ + /* + * Default is to return data MSB2LSB and enable the + * use of memory-mapped files and strip chopping when + * a file is opened read-only. + */ + tif->tif_flags = FILLORDER_MSB2LSB; + if (m == O_RDONLY) + tif->tif_flags |= TIFF_MAPPED; + +#ifdef STRIPCHOP_DEFAULT + if (m == O_RDONLY || m == O_RDWR) + tif->tif_flags |= STRIPCHOP_DEFAULT; +#endif + + /* + * Process library-specific flags in the open mode string. + * The following flags may be used to control intrinsic library + * behavior that may or may not be desirable (usually for + * compatibility with some application that claims to support + * TIFF but only supports some brain dead idea of what the + * vendor thinks TIFF is): + * + * 'l' use little-endian byte order for creating a file + * 'b' use big-endian byte order for creating a file + * 'L' read/write information using LSB2MSB bit order + * 'B' read/write information using MSB2LSB bit order + * 'H' read/write information using host bit order + * 'M' enable use of memory-mapped files when supported + * 'm' disable use of memory-mapped files + * 'C' enable strip chopping support when reading + * 'c' disable strip chopping support + * 'h' read TIFF header only, do not load the first IFD + * '4' ClassicTIFF for creating a file (default) + * '8' BigTIFF for creating a file + * 'D' enable use of deferred strip/tile offset/bytecount array loading. + * 'O' on-demand loading of values instead of whole array loading (implies + * D) + * + * The use of the 'l' and 'b' flags is strongly discouraged. + * These flags are provided solely because numerous vendors, + * typically on the PC, do not correctly support TIFF; they + * only support the Intel little-endian byte order. This + * support is not configured by default because it supports + * the violation of the TIFF spec that says that readers *MUST* + * support both byte orders. It is strongly recommended that + * you not use this feature except to deal with busted apps + * that write invalid TIFF. And even in those cases you should + * bang on the vendors to fix their software. + * + * The 'L', 'B', and 'H' flags are intended for applications + * that can optimize operations on data by using a particular + * bit order. By default the library returns data in MSB2LSB + * bit order for compatibility with older versions of this + * library. Returning data in the bit order of the native CPU + * makes the most sense but also requires applications to check + * the value of the FillOrder tag; something they probably do + * not do right now. + * + * The 'M' and 'm' flags are provided because some virtual memory + * systems exhibit poor behavior when large images are mapped. + * These options permit clients to control the use of memory-mapped + * files on a per-file basis. + * + * The 'C' and 'c' flags are provided because the library support + * for chopping up large strips into multiple smaller strips is not + * application-transparent and as such can cause problems. The 'c' + * option permits applications that only want to look at the tags, + * for example, to get the unadulterated TIFF tag information. + */ + for (cp = mode; *cp; cp++) + switch (*cp) + { + case 'b': +#ifndef WORDS_BIGENDIAN + if (m & O_CREAT) + tif->tif_flags |= TIFF_SWAB; +#endif + break; + case 'l': +#ifdef WORDS_BIGENDIAN + if ((m & O_CREAT)) + tif->tif_flags |= TIFF_SWAB; +#endif + break; + case 'B': + tif->tif_flags = + (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB; + break; + case 'L': + tif->tif_flags = + (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_LSB2MSB; + break; + case 'H': + tif->tif_flags = + (tif->tif_flags & ~TIFF_FILLORDER) | HOST_FILLORDER; + break; + case 'M': + if (m == O_RDONLY) + tif->tif_flags |= TIFF_MAPPED; + break; + case 'm': + if (m == O_RDONLY) + tif->tif_flags &= ~TIFF_MAPPED; + break; + case 'C': + if (m == O_RDONLY) + tif->tif_flags |= TIFF_STRIPCHOP; + break; + case 'c': + if (m == O_RDONLY) + tif->tif_flags &= ~TIFF_STRIPCHOP; + break; + case 'h': + tif->tif_flags |= TIFF_HEADERONLY; + break; + case '8': + if (m & O_CREAT) + tif->tif_flags |= TIFF_BIGTIFF; + break; + case 'D': + tif->tif_flags |= TIFF_DEFERSTRILELOAD; + break; + case 'O': + if (m == O_RDONLY) + tif->tif_flags |= + (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD); + break; + } #ifdef DEFER_STRILE_LOAD - /* Compatibility with old DEFER_STRILE_LOAD compilation flag */ - /* Probably unneeded, since to the best of my knowledge (E. Rouault) */ - /* GDAL was the only user of this, and will now use the new 'D' flag */ - tif->tif_flags |= TIFF_DEFERSTRILELOAD; + /* Compatibility with old DEFER_STRILE_LOAD compilation flag */ + /* Probably unneeded, since to the best of my knowledge (E. Rouault) */ + /* GDAL was the only user of this, and will now use the new 'D' flag */ + tif->tif_flags |= TIFF_DEFERSTRILELOAD; +#endif + + /* + * Read in TIFF header. + */ + if ((m & O_TRUNC) || + !ReadOK(tif, &tif->tif_header, sizeof(TIFFHeaderClassic))) + { + if (tif->tif_mode == O_RDONLY) + { + TIFFErrorExtR(tif, name, "Cannot read TIFF header"); + goto bad; + } +/* + * Setup header and write. + */ +#ifdef WORDS_BIGENDIAN + tif->tif_header.common.tiff_magic = + (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; +#else + tif->tif_header.common.tiff_magic = + (tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; +#endif + if (!(tif->tif_flags & TIFF_BIGTIFF)) + { + tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC; + tif->tif_header.classic.tiff_diroff = 0; + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&tif->tif_header.common.tiff_version); + tif->tif_header_size = sizeof(TIFFHeaderClassic); + } + else + { + tif->tif_header.common.tiff_version = TIFF_VERSION_BIG; + tif->tif_header.big.tiff_offsetsize = 8; + tif->tif_header.big.tiff_unused = 0; + tif->tif_header.big.tiff_diroff = 0; + if (tif->tif_flags & TIFF_SWAB) + { + TIFFSwabShort(&tif->tif_header.common.tiff_version); + TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); + } + tif->tif_header_size = sizeof(TIFFHeaderBig); + } + /* + * The doc for "fopen" for some STD_C_LIBs says that if you + * open a file for modify ("+"), then you must fseek (or + * fflush?) between any freads and fwrites. This is not + * necessary on most systems, but has been shown to be needed + * on Solaris. + */ + TIFFSeekFile(tif, 0, SEEK_SET); + if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) + { + TIFFErrorExtR(tif, name, "Error writing TIFF header"); + goto bad; + } + /* + * Setup the byte order handling. + */ + if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) + { +#ifndef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; +#endif + } + else + { +#ifdef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; +#endif + } + /* + * Setup default directory. + */ + if (!TIFFDefaultDirectory(tif)) + goto bad; + tif->tif_diroff = 0; + tif->tif_lastdiroff = 0; + tif->tif_dirlistoff = NULL; + tif->tif_dirlistdirn = NULL; + tif->tif_dirlistsize = 0; + tif->tif_dirnumber = 0; + return (tif); + } + /* + * Setup the byte order handling. + */ + if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN && + tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN +#if MDI_SUPPORT + && +#if HOST_BIGENDIAN + tif->tif_header.common.tiff_magic != MDI_BIGENDIAN +#else + tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN +#endif + ) + { + TIFFErrorExtR(tif, name, + "Not a TIFF or MDI file, bad magic number %" PRIu16 + " (0x%" PRIx16 ")", +#else + ) + { + TIFFErrorExtR(tif, name, + "Not a TIFF file, bad magic number %" PRIu16 + " (0x%" PRIx16 ")", +#endif + tif->tif_header.common.tiff_magic, + tif->tif_header.common.tiff_magic); + goto bad; + } + if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) + { +#ifndef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; +#endif + } + else + { +#ifdef WORDS_BIGENDIAN + tif->tif_flags |= TIFF_SWAB; #endif + } + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabShort(&tif->tif_header.common.tiff_version); + if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC) && + (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) + { + TIFFErrorExtR(tif, name, + "Not a TIFF file, bad version number %" PRIu16 + " (0x%" PRIx16 ")", + tif->tif_header.common.tiff_version, + tif->tif_header.common.tiff_version); + goto bad; + } + if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC) + { + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabLong(&tif->tif_header.classic.tiff_diroff); + tif->tif_header_size = sizeof(TIFFHeaderClassic); + } + else + { + if (!ReadOK(tif, + ((uint8_t *)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), + (sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic)))) + { + TIFFErrorExtR(tif, name, "Cannot read TIFF header"); + goto bad; + } + if (tif->tif_flags & TIFF_SWAB) + { + TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); + TIFFSwabLong8(&tif->tif_header.big.tiff_diroff); + } + if (tif->tif_header.big.tiff_offsetsize != 8) + { + TIFFErrorExtR(tif, name, + "Not a TIFF file, bad BigTIFF offsetsize %" PRIu16 + " (0x%" PRIx16 ")", + tif->tif_header.big.tiff_offsetsize, + tif->tif_header.big.tiff_offsetsize); + goto bad; + } + if (tif->tif_header.big.tiff_unused != 0) + { + TIFFErrorExtR(tif, name, + "Not a TIFF file, bad BigTIFF unused %" PRIu16 + " (0x%" PRIx16 ")", + tif->tif_header.big.tiff_unused, + tif->tif_header.big.tiff_unused); + goto bad; + } + tif->tif_header_size = sizeof(TIFFHeaderBig); + tif->tif_flags |= TIFF_BIGTIFF; + } + tif->tif_flags |= TIFF_MYBUFFER; + tif->tif_rawcp = tif->tif_rawdata = 0; + tif->tif_rawdatasize = 0; + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = 0; - /* - * Read in TIFF header. - */ - if ((m & O_TRUNC) || - !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) { - if (tif->tif_mode == O_RDONLY) { - TIFFErrorExtR(tif, name, - "Cannot read TIFF header"); - goto bad; - } - /* - * Setup header and write. - */ - #ifdef WORDS_BIGENDIAN - tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB) - ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; - #else - tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB) - ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; - #endif - if (!(tif->tif_flags&TIFF_BIGTIFF)) - { - tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC; - tif->tif_header.classic.tiff_diroff = 0; - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&tif->tif_header.common.tiff_version); - tif->tif_header_size = sizeof(TIFFHeaderClassic); - } - else - { - tif->tif_header.common.tiff_version = TIFF_VERSION_BIG; - tif->tif_header.big.tiff_offsetsize = 8; - tif->tif_header.big.tiff_unused = 0; - tif->tif_header.big.tiff_diroff = 0; - if (tif->tif_flags & TIFF_SWAB) - { - TIFFSwabShort(&tif->tif_header.common.tiff_version); - TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); - } - tif->tif_header_size = sizeof (TIFFHeaderBig); - } - /* - * The doc for "fopen" for some STD_C_LIBs says that if you - * open a file for modify ("+"), then you must fseek (or - * fflush?) between any freads and fwrites. This is not - * necessary on most systems, but has been shown to be needed - * on Solaris. - */ - TIFFSeekFile( tif, 0, SEEK_SET ); - if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) { - TIFFErrorExtR(tif, name, - "Error writing TIFF header"); - goto bad; - } - /* - * Setup the byte order handling. - */ - if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { - #ifndef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; - #endif - } else { - #ifdef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; - #endif - } - /* - * Setup default directory. - */ - if (!TIFFDefaultDirectory(tif)) - goto bad; - tif->tif_diroff = 0; - tif->tif_lastdiroff = 0; - tif->tif_dirlistoff = NULL; - tif->tif_dirlistdirn = NULL; - tif->tif_dirlistsize = 0; - tif->tif_dirnumber = 0; - return (tif); - } - /* - * Setup the byte order handling. - */ - if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN && - tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN - #if MDI_SUPPORT - && - #if HOST_BIGENDIAN - tif->tif_header.common.tiff_magic != MDI_BIGENDIAN - #else - tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN - #endif - ) { - TIFFErrorExtR(tif, name, - "Not a TIFF or MDI file, bad magic number %"PRIu16" (0x%"PRIx16")", - #else - ) { - TIFFErrorExtR(tif, name, - "Not a TIFF file, bad magic number %"PRIu16" (0x%"PRIx16")", - #endif - tif->tif_header.common.tiff_magic, - tif->tif_header.common.tiff_magic); - goto bad; - } - if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { - #ifndef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; - #endif - } else { - #ifdef WORDS_BIGENDIAN - tif->tif_flags |= TIFF_SWAB; - #endif - } - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabShort(&tif->tif_header.common.tiff_version); - if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&& - (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) { - TIFFErrorExtR(tif, name, - "Not a TIFF file, bad version number %"PRIu16" (0x%"PRIx16")", - tif->tif_header.common.tiff_version, - tif->tif_header.common.tiff_version); - goto bad; - } - if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC) - { - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabLong(&tif->tif_header.classic.tiff_diroff); - tif->tif_header_size = sizeof(TIFFHeaderClassic); - } - else - { - if (!ReadOK(tif, ((uint8_t*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic)))) - { - TIFFErrorExtR(tif, name, - "Cannot read TIFF header"); - goto bad; - } - if (tif->tif_flags & TIFF_SWAB) - { - TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); - TIFFSwabLong8(&tif->tif_header.big.tiff_diroff); - } - if (tif->tif_header.big.tiff_offsetsize != 8) - { - TIFFErrorExtR(tif, name, - "Not a TIFF file, bad BigTIFF offsetsize %"PRIu16" (0x%"PRIx16")", - tif->tif_header.big.tiff_offsetsize, - tif->tif_header.big.tiff_offsetsize); - goto bad; - } - if (tif->tif_header.big.tiff_unused != 0) - { - TIFFErrorExtR(tif, name, - "Not a TIFF file, bad BigTIFF unused %"PRIu16" (0x%"PRIx16")", - tif->tif_header.big.tiff_unused, - tif->tif_header.big.tiff_unused); - goto bad; - } - tif->tif_header_size = sizeof(TIFFHeaderBig); - tif->tif_flags |= TIFF_BIGTIFF; - } - tif->tif_flags |= TIFF_MYBUFFER; - tif->tif_rawcp = tif->tif_rawdata = 0; - tif->tif_rawdatasize = 0; - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = 0; - - switch (mode[0]) { - case 'r': - if (!(tif->tif_flags&TIFF_BIGTIFF)) - tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff; - else - tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff; - /* - * Try to use a memory-mapped file if the client - * has not explicitly suppressed usage with the - * 'm' flag in the open mode (see above). - */ - if (tif->tif_flags & TIFF_MAPPED) - { - toff_t n; - if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n)) - { - tif->tif_size=(tmsize_t)n; - assert((toff_t)tif->tif_size==n); - } - else - tif->tif_flags &= ~TIFF_MAPPED; - } - /* - * Sometimes we do not want to read the first directory (for example, - * it may be broken) and want to proceed to other directories. I this - * case we use the TIFF_HEADERONLY flag to open file and return - * immediately after reading TIFF header. - */ - if (tif->tif_flags & TIFF_HEADERONLY) - return (tif); - - /* - * Setup initial directory. - */ - if (TIFFReadDirectory(tif)) { - return (tif); - } - break; - case 'a': - /* - * New directories are automatically append - * to the end of the directory chain when they - * are written out (see TIFFWriteDirectory). - */ - if (!TIFFDefaultDirectory(tif)) - goto bad; - return (tif); - } + switch (mode[0]) + { + case 'r': + if (!(tif->tif_flags & TIFF_BIGTIFF)) + tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff; + else + tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff; + /* + * Try to use a memory-mapped file if the client + * has not explicitly suppressed usage with the + * 'm' flag in the open mode (see above). + */ + if (tif->tif_flags & TIFF_MAPPED) + { + toff_t n; + if (TIFFMapFileContents(tif, (void **)(&tif->tif_base), &n)) + { + tif->tif_size = (tmsize_t)n; + assert((toff_t)tif->tif_size == n); + } + else + tif->tif_flags &= ~TIFF_MAPPED; + } + /* + * Sometimes we do not want to read the first directory (for + * example, it may be broken) and want to proceed to other + * directories. I this case we use the TIFF_HEADERONLY flag to open + * file and return immediately after reading TIFF header. + */ + if (tif->tif_flags & TIFF_HEADERONLY) + return (tif); + + /* + * Setup initial directory. + */ + if (TIFFReadDirectory(tif)) + { + return (tif); + } + break; + case 'a': + /* + * New directories are automatically append + * to the end of the directory chain when they + * are written out (see TIFFWriteDirectory). + */ + if (!TIFFDefaultDirectory(tif)) + goto bad; + return (tif); + } bad: - tif->tif_mode = O_RDONLY; /* XXX avoid flush */ - TIFFCleanup(tif); + tif->tif_mode = O_RDONLY; /* XXX avoid flush */ + TIFFCleanup(tif); bad2: - return ((TIFF*)0); + return ((TIFF *)0); } /* @@ -630,233 +653,154 @@ bad2: /* * Return open file's name. */ -const char * -TIFFFileName(TIFF* tif) -{ - return (tif->tif_name); -} +const char *TIFFFileName(TIFF *tif) { return (tif->tif_name); } /* * Set the file name. */ -const char * -TIFFSetFileName(TIFF* tif, const char *name) +const char *TIFFSetFileName(TIFF *tif, const char *name) { - const char* old_name = tif->tif_name; - tif->tif_name = (char *)name; - return (old_name); + const char *old_name = tif->tif_name; + tif->tif_name = (char *)name; + return (old_name); } /* * Return open file's I/O descriptor. */ -int -TIFFFileno(TIFF* tif) -{ - return (tif->tif_fd); -} +int TIFFFileno(TIFF *tif) { return (tif->tif_fd); } /* * Set open file's I/O descriptor, and return previous value. */ -int -TIFFSetFileno(TIFF* tif, int fd) +int TIFFSetFileno(TIFF *tif, int fd) { - int old_fd = tif->tif_fd; - tif->tif_fd = fd; - return old_fd; + int old_fd = tif->tif_fd; + tif->tif_fd = fd; + return old_fd; } /* * Return open file's clientdata. */ -thandle_t -TIFFClientdata(TIFF* tif) -{ - return (tif->tif_clientdata); -} +thandle_t TIFFClientdata(TIFF *tif) { return (tif->tif_clientdata); } /* * Set open file's clientdata, and return previous value. */ -thandle_t -TIFFSetClientdata(TIFF* tif, thandle_t newvalue) +thandle_t TIFFSetClientdata(TIFF *tif, thandle_t newvalue) { - thandle_t m = tif->tif_clientdata; - tif->tif_clientdata = newvalue; - return m; + thandle_t m = tif->tif_clientdata; + tif->tif_clientdata = newvalue; + return m; } /* * Return read/write mode. */ -int -TIFFGetMode(TIFF* tif) -{ - return (tif->tif_mode); -} +int TIFFGetMode(TIFF *tif) { return (tif->tif_mode); } /* * Return read/write mode. */ -int -TIFFSetMode(TIFF* tif, int mode) +int TIFFSetMode(TIFF *tif, int mode) { - int old_mode = tif->tif_mode; - tif->tif_mode = mode; - return (old_mode); + int old_mode = tif->tif_mode; + tif->tif_mode = mode; + return (old_mode); } /* * Return nonzero if file is organized in * tiles; zero if organized as strips. */ -int -TIFFIsTiled(TIFF* tif) -{ - return (isTiled(tif)); -} +int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); } /* * Return current row being read/written. */ -uint32_t -TIFFCurrentRow(TIFF* tif) -{ - return (tif->tif_row); -} +uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); } /* * Return index of the current directory. */ -uint16_t -TIFFCurrentDirectory(TIFF* tif) -{ - return (tif->tif_curdir); -} +uint16_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); } /* * Return current strip. */ -uint32_t -TIFFCurrentStrip(TIFF* tif) -{ - return (tif->tif_curstrip); -} +uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); } /* * Return current tile. */ -uint32_t -TIFFCurrentTile(TIFF* tif) -{ - return (tif->tif_curtile); -} +uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); } /* * Return nonzero if the file has byte-swapped data. */ -int -TIFFIsByteSwapped(TIFF* tif) -{ - return ((tif->tif_flags & TIFF_SWAB) != 0); -} +int TIFFIsByteSwapped(TIFF *tif) { return ((tif->tif_flags & TIFF_SWAB) != 0); } /* * Return nonzero if the data is returned up-sampled. */ -int -TIFFIsUpSampled(TIFF* tif) -{ - return (isUpSampled(tif)); -} +int TIFFIsUpSampled(TIFF *tif) { return (isUpSampled(tif)); } /* * Return nonzero if the data is returned in MSB-to-LSB bit order. */ -int -TIFFIsMSB2LSB(TIFF* tif) -{ - return (isFillOrder(tif, FILLORDER_MSB2LSB)); -} +int TIFFIsMSB2LSB(TIFF *tif) { return (isFillOrder(tif, FILLORDER_MSB2LSB)); } /* * Return nonzero if given file was written in big-endian order. */ -int -TIFFIsBigEndian(TIFF* tif) +int TIFFIsBigEndian(TIFF *tif) { - return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN); + return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN); } /* * Return nonzero if given file is BigTIFF style. */ -int -TIFFIsBigTIFF(TIFF *tif) +int TIFFIsBigTIFF(TIFF *tif) { - return (tif->tif_header.common.tiff_version == TIFF_VERSION_BIG); + return (tif->tif_header.common.tiff_version == TIFF_VERSION_BIG); } /* * Return pointer to file read method. */ -TIFFReadWriteProc -TIFFGetReadProc(TIFF* tif) -{ - return (tif->tif_readproc); -} +TIFFReadWriteProc TIFFGetReadProc(TIFF *tif) { return (tif->tif_readproc); } /* * Return pointer to file write method. */ -TIFFReadWriteProc -TIFFGetWriteProc(TIFF* tif) -{ - return (tif->tif_writeproc); -} +TIFFReadWriteProc TIFFGetWriteProc(TIFF *tif) { return (tif->tif_writeproc); } /* * Return pointer to file seek method. */ -TIFFSeekProc -TIFFGetSeekProc(TIFF* tif) -{ - return (tif->tif_seekproc); -} +TIFFSeekProc TIFFGetSeekProc(TIFF *tif) { return (tif->tif_seekproc); } /* * Return pointer to file close method. */ -TIFFCloseProc -TIFFGetCloseProc(TIFF* tif) -{ - return (tif->tif_closeproc); -} +TIFFCloseProc TIFFGetCloseProc(TIFF *tif) { return (tif->tif_closeproc); } /* * Return pointer to file size requesting method. */ -TIFFSizeProc -TIFFGetSizeProc(TIFF* tif) -{ - return (tif->tif_sizeproc); -} +TIFFSizeProc TIFFGetSizeProc(TIFF *tif) { return (tif->tif_sizeproc); } /* * Return pointer to memory mapping method. */ -TIFFMapFileProc -TIFFGetMapFileProc(TIFF* tif) -{ - return (tif->tif_mapproc); -} +TIFFMapFileProc TIFFGetMapFileProc(TIFF *tif) { return (tif->tif_mapproc); } /* * Return pointer to memory unmapping method. */ -TIFFUnmapFileProc -TIFFGetUnmapFileProc(TIFF* tif) +TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *tif) { - return (tif->tif_unmapproc); + return (tif->tif_unmapproc); } diff --git a/libtiff/tif_packbits.c b/libtiff/tif_packbits.c index ef00b44c..62849f8f 100644 --- a/libtiff/tif_packbits.c +++ b/libtiff/tif_packbits.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -31,157 +31,178 @@ */ #include <stdio.h> -static int -PackBitsPreEncode(TIFF* tif, uint16_t s) +static int PackBitsPreEncode(TIFF *tif, uint16_t s) { - (void) s; + (void)s; - tif->tif_data = (uint8_t*)_TIFFmallocExt(tif, sizeof(tmsize_t)); - if (tif->tif_data == NULL) - return (0); - /* - * Calculate the scanline/tile-width size in bytes. - */ - if (isTiled(tif)) - *(tmsize_t*)tif->tif_data = TIFFTileRowSize(tif); - else - *(tmsize_t*)tif->tif_data = TIFFScanlineSize(tif); - return (1); + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(tmsize_t)); + if (tif->tif_data == NULL) + return (0); + /* + * Calculate the scanline/tile-width size in bytes. + */ + if (isTiled(tif)) + *(tmsize_t *)tif->tif_data = TIFFTileRowSize(tif); + else + *(tmsize_t *)tif->tif_data = TIFFScanlineSize(tif); + return (1); } -static int -PackBitsPostEncode(TIFF* tif) +static int PackBitsPostEncode(TIFF *tif) { - if (tif->tif_data) - _TIFFfreeExt(tif, tif->tif_data); - return (1); + if (tif->tif_data) + _TIFFfreeExt(tif, tif->tif_data); + return (1); } /* * Encode a run of pixels. */ -static int -PackBitsEncode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) +static int PackBitsEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s) { - unsigned char* bp = (unsigned char*) buf; - uint8_t* op; - uint8_t* ep; - uint8_t* lastliteral; - long n, slop; - int b; - enum { BASE, LITERAL, RUN, LITERAL_RUN } state; + unsigned char *bp = (unsigned char *)buf; + uint8_t *op; + uint8_t *ep; + uint8_t *lastliteral; + long n, slop; + int b; + enum + { + BASE, + LITERAL, + RUN, + LITERAL_RUN + } state; - (void) s; - op = tif->tif_rawcp; - ep = tif->tif_rawdata + tif->tif_rawdatasize; - state = BASE; - lastliteral = 0; - while (cc > 0) { - /* - * Find the longest string of identical bytes. - */ - b = *bp++; - cc--; - n = 1; - for (; cc > 0 && b == *bp; cc--, bp++) - n++; - again: - if (op + 2 >= ep) { /* insure space for new data */ - /* - * Be careful about writing the last - * literal. Must write up to that point - * and then copy the remainder to the - * front of the buffer. - */ - if (state == LITERAL || state == LITERAL_RUN) { - slop = (long)(op - lastliteral); - tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp); - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - while (slop-- > 0) - *op++ = *lastliteral++; - lastliteral = tif->tif_rawcp; - } else { - tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); - if (!TIFFFlushData1(tif)) - return (0); - op = tif->tif_rawcp; - } - } - switch (state) { - case BASE: /* initial state, set run/literal */ - if (n > 1) { - state = RUN; - if (n > 128) { - *op++ = (uint8_t) -127; - *op++ = (uint8_t) b; - n -= 128; - goto again; - } - *op++ = (uint8_t)(-(n - 1)); - *op++ = (uint8_t) b; - } else { - lastliteral = op; - *op++ = 0; - *op++ = (uint8_t) b; - state = LITERAL; - } - break; - case LITERAL: /* last object was literal string */ - if (n > 1) { - state = LITERAL_RUN; - if (n > 128) { - *op++ = (uint8_t) -127; - *op++ = (uint8_t) b; - n -= 128; - goto again; - } - *op++ = (uint8_t)(-(n - 1)); /* encode run */ - *op++ = (uint8_t) b; - } else { /* extend literal */ - if (++(*lastliteral) == 127) - state = BASE; - *op++ = (uint8_t) b; - } - break; - case RUN: /* last object was run */ - if (n > 1) { - if (n > 128) { - *op++ = (uint8_t) -127; - *op++ = (uint8_t) b; - n -= 128; - goto again; - } - *op++ = (uint8_t)(-(n - 1)); - *op++ = (uint8_t) b; - } else { - lastliteral = op; - *op++ = 0; - *op++ = (uint8_t) b; - state = LITERAL; - } - break; - case LITERAL_RUN: /* literal followed by a run */ - /* - * Check to see if previous run should - * be converted to a literal, in which - * case we convert literal-run-literal - * to a single literal. - */ - if (n == 1 && op[-2] == (uint8_t) -1 && - *lastliteral < 126) { - state = (((*lastliteral) += 2) == 127 ? - BASE : LITERAL); - op[-2] = op[-1]; /* replicate */ - } else - state = RUN; - goto again; - } - } - tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); - tif->tif_rawcp = op; - return (1); + (void)s; + op = tif->tif_rawcp; + ep = tif->tif_rawdata + tif->tif_rawdatasize; + state = BASE; + lastliteral = 0; + while (cc > 0) + { + /* + * Find the longest string of identical bytes. + */ + b = *bp++; + cc--; + n = 1; + for (; cc > 0 && b == *bp; cc--, bp++) + n++; + again: + if (op + 2 >= ep) + { /* insure space for new data */ + /* + * Be careful about writing the last + * literal. Must write up to that point + * and then copy the remainder to the + * front of the buffer. + */ + if (state == LITERAL || state == LITERAL_RUN) + { + slop = (long)(op - lastliteral); + tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp); + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + while (slop-- > 0) + *op++ = *lastliteral++; + lastliteral = tif->tif_rawcp; + } + else + { + tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); + if (!TIFFFlushData1(tif)) + return (0); + op = tif->tif_rawcp; + } + } + switch (state) + { + case BASE: /* initial state, set run/literal */ + if (n > 1) + { + state = RUN; + if (n > 128) + { + *op++ = (uint8_t)-127; + *op++ = (uint8_t)b; + n -= 128; + goto again; + } + *op++ = (uint8_t)(-(n - 1)); + *op++ = (uint8_t)b; + } + else + { + lastliteral = op; + *op++ = 0; + *op++ = (uint8_t)b; + state = LITERAL; + } + break; + case LITERAL: /* last object was literal string */ + if (n > 1) + { + state = LITERAL_RUN; + if (n > 128) + { + *op++ = (uint8_t)-127; + *op++ = (uint8_t)b; + n -= 128; + goto again; + } + *op++ = (uint8_t)(-(n - 1)); /* encode run */ + *op++ = (uint8_t)b; + } + else + { /* extend literal */ + if (++(*lastliteral) == 127) + state = BASE; + *op++ = (uint8_t)b; + } + break; + case RUN: /* last object was run */ + if (n > 1) + { + if (n > 128) + { + *op++ = (uint8_t)-127; + *op++ = (uint8_t)b; + n -= 128; + goto again; + } + *op++ = (uint8_t)(-(n - 1)); + *op++ = (uint8_t)b; + } + else + { + lastliteral = op; + *op++ = 0; + *op++ = (uint8_t)b; + state = LITERAL; + } + break; + case LITERAL_RUN: /* literal followed by a run */ + /* + * Check to see if previous run should + * be converted to a literal, in which + * case we convert literal-run-literal + * to a single literal. + */ + if (n == 1 && op[-2] == (uint8_t)-1 && *lastliteral < 126) + { + state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL); + op[-2] = op[-1]; /* replicate */ + } + else + state = RUN; + goto again; + } + } + tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp); + tif->tif_rawcp = op; + return (1); } /* @@ -191,104 +212,112 @@ PackBitsEncode(TIFF* tif, uint8_t* buf, tmsize_t cc, uint16_t s) * the decoder if data is read, for example, by scanlines * when it was encoded by strips. */ -static int -PackBitsEncodeChunk(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int PackBitsEncodeChunk(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - tmsize_t rowsize = *(tmsize_t*)tif->tif_data; + tmsize_t rowsize = *(tmsize_t *)tif->tif_data; + + while (cc > 0) + { + tmsize_t chunk = rowsize; - while (cc > 0) { - tmsize_t chunk = rowsize; - - if( cc < chunk ) - chunk = cc; + if (cc < chunk) + chunk = cc; - if (PackBitsEncode(tif, bp, chunk, s) < 0) - return (-1); - bp += chunk; - cc -= chunk; - } - return (1); + if (PackBitsEncode(tif, bp, chunk, s) < 0) + return (-1); + bp += chunk; + cc -= chunk; + } + return (1); } -static int -PackBitsDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) +static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "PackBitsDecode"; - int8_t *bp; - tmsize_t cc; - long n; - int b; + static const char module[] = "PackBitsDecode"; + int8_t *bp; + tmsize_t cc; + long n; + int b; - (void) s; - bp = (int8_t*) tif->tif_rawcp; - cc = tif->tif_rawcc; - while (cc > 0 && occ > 0) { - n = (long) *bp++; - cc--; - if (n < 0) { /* replicate next byte -n+1 times */ - if (n == -128) /* nop */ - continue; - n = -n + 1; - if( occ < (tmsize_t)n ) - { - TIFFWarningExtR(tif, module, - "Discarding %"TIFF_SSIZE_FORMAT" bytes to avoid buffer overrun", - (tmsize_t)n - occ); - n = (long)occ; - } - if( cc == 0 ) - { - TIFFWarningExtR(tif, module, - "Terminating PackBitsDecode due to lack of data."); - break; - } - occ -= n; - b = *bp++; - cc--; - while (n-- > 0) - *op++ = (uint8_t) b; - } else { /* copy next n+1 bytes literally */ - if (occ < (tmsize_t)(n + 1)) - { - TIFFWarningExtR(tif, module, - "Discarding %"TIFF_SSIZE_FORMAT" bytes to avoid buffer overrun", - (tmsize_t)n - occ + 1); - n = (long)occ - 1; - } - if (cc < (tmsize_t) (n+1)) - { - TIFFWarningExtR(tif, module, - "Terminating PackBitsDecode due to lack of data."); - break; - } - _TIFFmemcpy(op, bp, ++n); - op += n; occ -= n; - bp += n; cc -= n; - } - } - tif->tif_rawcp = (uint8_t*) bp; - tif->tif_rawcc = cc; - if (occ > 0) { - TIFFErrorExtR(tif, module, - "Not enough data for scanline %"PRIu32, - tif->tif_row); - return (0); - } - return (1); + (void)s; + bp = (int8_t *)tif->tif_rawcp; + cc = tif->tif_rawcc; + while (cc > 0 && occ > 0) + { + n = (long)*bp++; + cc--; + if (n < 0) + { /* replicate next byte -n+1 times */ + if (n == -128) /* nop */ + continue; + n = -n + 1; + if (occ < (tmsize_t)n) + { + TIFFWarningExtR(tif, module, + "Discarding %" TIFF_SSIZE_FORMAT + " bytes to avoid buffer overrun", + (tmsize_t)n - occ); + n = (long)occ; + } + if (cc == 0) + { + TIFFWarningExtR( + tif, module, + "Terminating PackBitsDecode due to lack of data."); + break; + } + occ -= n; + b = *bp++; + cc--; + while (n-- > 0) + *op++ = (uint8_t)b; + } + else + { /* copy next n+1 bytes literally */ + if (occ < (tmsize_t)(n + 1)) + { + TIFFWarningExtR(tif, module, + "Discarding %" TIFF_SSIZE_FORMAT + " bytes to avoid buffer overrun", + (tmsize_t)n - occ + 1); + n = (long)occ - 1; + } + if (cc < (tmsize_t)(n + 1)) + { + TIFFWarningExtR( + tif, module, + "Terminating PackBitsDecode due to lack of data."); + break; + } + _TIFFmemcpy(op, bp, ++n); + op += n; + occ -= n; + bp += n; + cc -= n; + } + } + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + if (occ > 0) + { + TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32, + tif->tif_row); + return (0); + } + return (1); } -int -TIFFInitPackBits(TIFF* tif, int scheme) +int TIFFInitPackBits(TIFF *tif, int scheme) { - (void) scheme; - tif->tif_decoderow = PackBitsDecode; - tif->tif_decodestrip = PackBitsDecode; - tif->tif_decodetile = PackBitsDecode; - tif->tif_preencode = PackBitsPreEncode; - tif->tif_postencode = PackBitsPostEncode; - tif->tif_encoderow = PackBitsEncode; - tif->tif_encodestrip = PackBitsEncodeChunk; - tif->tif_encodetile = PackBitsEncodeChunk; - return (1); + (void)scheme; + tif->tif_decoderow = PackBitsDecode; + tif->tif_decodestrip = PackBitsDecode; + tif->tif_decodetile = PackBitsDecode; + tif->tif_preencode = PackBitsPreEncode; + tif->tif_postencode = PackBitsPostEncode; + tif->tif_encoderow = PackBitsEncode; + tif->tif_encodestrip = PackBitsEncodeChunk; + tif->tif_encodetile = PackBitsEncodeChunk; + return (1); } #endif /* PACKBITS_SUPPORT */ diff --git a/libtiff/tif_pixarlog.c b/libtiff/tif_pixarlog.c index 4377a4ea..5c0346b6 100644 --- a/libtiff/tif_pixarlog.c +++ b/libtiff/tif_pixarlog.c @@ -2,23 +2,23 @@ * Copyright (c) 1996-1997 Sam Leffler * Copyright (c) 1996 Pixar * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Pixar, Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -32,10 +32,10 @@ * Contributed by Dan McCoy. * * PixarLog film support uses the TIFF library to store companded - * 11 bit values into a tiff file, which are compressed using the - * zip compressor. + * 11 bit values into a tiff file, which are compressed using the + * zip compressor. * - * The codec can take as input and produce as output 32-bit IEEE float values + * The codec can take as input and produce as output 32-bit IEEE float values * as well as 16-bit or 8-bit unsigned integer values. * * On writing any of the above are converted into the internal @@ -49,7 +49,7 @@ * than the human eye can perceive with extra room to allow for * error introduced by further image computation. As with any quantized * color format, it is possible to perform image calculations which - * expose the quantization error. This format should certainly be less + * expose the quantization error. This format should certainly be less * susceptible to such errors than standard 8-bit encodings, but more * susceptible than straight 16-bit or 32-bit encodings. * @@ -90,363 +90,429 @@ #include "tif_predict.h" #include "zlib.h" +#include <math.h> #include <stdio.h> #include <stdlib.h> -#include <math.h> /* Tables for converting to/from 11 bit coded values */ -#define TSIZE 2048 /* decode table size (11-bit tokens) */ -#define TSIZEP1 2049 /* Plus one for slop */ -#define ONE 1250 /* token value of 1.0 exactly */ -#define RATIO 1.004 /* nominal ratio for log part */ - -#define CODE_MASK 0x7ff /* 11 bits. */ - -static float Fltsize; -static float LogK1, LogK2; - -#define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); } +#define TSIZE 2048 /* decode table size (11-bit tokens) */ +#define TSIZEP1 2049 /* Plus one for slop */ +#define ONE 1250 /* token value of 1.0 exactly */ +#define RATIO 1.004 /* nominal ratio for log part */ + +#define CODE_MASK 0x7ff /* 11 bits. */ + +static float Fltsize; +static float LogK1, LogK2; + +#define REPEAT(n, op) \ + { \ + int i; \ + i = n; \ + do \ + { \ + i--; \ + op; \ + } while (i > 0); \ + } -static void -horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op, - float *ToLinearF) +static void horizontalAccumulateF(uint16_t *wp, int n, int stride, float *op, + float *ToLinearF) { - register unsigned int cr, cg, cb, ca, mask; - register float t0, t1, t2, t3; - - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - t0 = ToLinearF[cr = (wp[0] & mask)]; - t1 = ToLinearF[cg = (wp[1] & mask)]; - t2 = ToLinearF[cb = (wp[2] & mask)]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - n -= 3; - while (n > 0) { - wp += 3; - op += 3; - n -= 3; - t0 = ToLinearF[(cr += wp[0]) & mask]; - t1 = ToLinearF[(cg += wp[1]) & mask]; - t2 = ToLinearF[(cb += wp[2]) & mask]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - } - } else if (stride == 4) { - t0 = ToLinearF[cr = (wp[0] & mask)]; - t1 = ToLinearF[cg = (wp[1] & mask)]; - t2 = ToLinearF[cb = (wp[2] & mask)]; - t3 = ToLinearF[ca = (wp[3] & mask)]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - n -= 4; - while (n > 0) { - wp += 4; - op += 4; - n -= 4; - t0 = ToLinearF[(cr += wp[0]) & mask]; - t1 = ToLinearF[(cg += wp[1]) & mask]; - t2 = ToLinearF[(cb += wp[2]) & mask]; - t3 = ToLinearF[(ca += wp[3]) & mask]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - } - } else { - REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++) - n -= stride; - } - } + register unsigned int cr, cg, cb, ca, mask; + register float t0, t1, t2, t3; + + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + t0 = ToLinearF[cr = (wp[0] & mask)]; + t1 = ToLinearF[cg = (wp[1] & mask)]; + t2 = ToLinearF[cb = (wp[2] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + n -= 3; + while (n > 0) + { + wp += 3; + op += 3; + n -= 3; + t0 = ToLinearF[(cr += wp[0]) & mask]; + t1 = ToLinearF[(cg += wp[1]) & mask]; + t2 = ToLinearF[(cb += wp[2]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + } + } + else if (stride == 4) + { + t0 = ToLinearF[cr = (wp[0] & mask)]; + t1 = ToLinearF[cg = (wp[1] & mask)]; + t2 = ToLinearF[cb = (wp[2] & mask)]; + t3 = ToLinearF[ca = (wp[3] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 4; + while (n > 0) + { + wp += 4; + op += 4; + n -= 4; + t0 = ToLinearF[(cr += wp[0]) & mask]; + t1 = ToLinearF[(cg += wp[1]) & mask]; + t2 = ToLinearF[(cb += wp[2]) & mask]; + t3 = ToLinearF[(ca += wp[3]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } + else + { + REPEAT(stride, *op = ToLinearF[*wp & mask]; wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; *op = ToLinearF[*wp & mask]; + wp++; op++) + n -= stride; + } + } } } -static void -horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op, - float *ToLinearF) +static void horizontalAccumulate12(uint16_t *wp, int n, int stride, int16_t *op, + float *ToLinearF) { - register unsigned int cr, cg, cb, ca, mask; - register float t0, t1, t2, t3; + register unsigned int cr, cg, cb, ca, mask; + register float t0, t1, t2, t3; #define SCALE12 2048.0F -#define CLAMP12(t) (((t) < 3071) ? (uint16_t) (t) : 3071) - - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; - t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; - t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - n -= 3; - while (n > 0) { - wp += 3; - op += 3; - n -= 3; - t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; - t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; - t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - } - } else if (stride == 4) { - t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; - t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; - t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; - t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - op[3] = CLAMP12(t3); - n -= 4; - while (n > 0) { - wp += 4; - op += 4; - n -= 4; - t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; - t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; - t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; - t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12; - op[0] = CLAMP12(t0); - op[1] = CLAMP12(t1); - op[2] = CLAMP12(t2); - op[3] = CLAMP12(t3); - } - } else { - REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12; - *op = CLAMP12(t0); wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12; - *op = CLAMP12(t0); wp++; op++) - n -= stride; - } - } +#define CLAMP12(t) (((t) < 3071) ? (uint16_t)(t) : 3071) + + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; + t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; + t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + n -= 3; + while (n > 0) + { + wp += 3; + op += 3; + n -= 3; + t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; + t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; + t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + } + } + else if (stride == 4) + { + t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12; + t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12; + t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12; + t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + op[3] = CLAMP12(t3); + n -= 4; + while (n > 0) + { + wp += 4; + op += 4; + n -= 4; + t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12; + t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12; + t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12; + t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12; + op[0] = CLAMP12(t0); + op[1] = CLAMP12(t1); + op[2] = CLAMP12(t2); + op[3] = CLAMP12(t3); + } + } + else + { + REPEAT(stride, t0 = ToLinearF[*wp & mask] * SCALE12; + *op = CLAMP12(t0); wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; + t0 = ToLinearF[wp[stride] & mask] * SCALE12; + *op = CLAMP12(t0); wp++; op++) + n -= stride; + } + } } } -static void -horizontalAccumulate16(uint16_t *wp, int n, int stride, uint16_t *op, - uint16_t *ToLinear16) +static void horizontalAccumulate16(uint16_t *wp, int n, int stride, + uint16_t *op, uint16_t *ToLinear16) { - register unsigned int cr, cg, cb, ca, mask; - - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - op[0] = ToLinear16[cr = (wp[0] & mask)]; - op[1] = ToLinear16[cg = (wp[1] & mask)]; - op[2] = ToLinear16[cb = (wp[2] & mask)]; - n -= 3; - while (n > 0) { - wp += 3; - op += 3; - n -= 3; - op[0] = ToLinear16[(cr += wp[0]) & mask]; - op[1] = ToLinear16[(cg += wp[1]) & mask]; - op[2] = ToLinear16[(cb += wp[2]) & mask]; - } - } else if (stride == 4) { - op[0] = ToLinear16[cr = (wp[0] & mask)]; - op[1] = ToLinear16[cg = (wp[1] & mask)]; - op[2] = ToLinear16[cb = (wp[2] & mask)]; - op[3] = ToLinear16[ca = (wp[3] & mask)]; - n -= 4; - while (n > 0) { - wp += 4; - op += 4; - n -= 4; - op[0] = ToLinear16[(cr += wp[0]) & mask]; - op[1] = ToLinear16[(cg += wp[1]) & mask]; - op[2] = ToLinear16[(cb += wp[2]) & mask]; - op[3] = ToLinear16[(ca += wp[3]) & mask]; - } - } else { - REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++) - n -= stride; - } - } + register unsigned int cr, cg, cb, ca, mask; + + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + op[0] = ToLinear16[cr = (wp[0] & mask)]; + op[1] = ToLinear16[cg = (wp[1] & mask)]; + op[2] = ToLinear16[cb = (wp[2] & mask)]; + n -= 3; + while (n > 0) + { + wp += 3; + op += 3; + n -= 3; + op[0] = ToLinear16[(cr += wp[0]) & mask]; + op[1] = ToLinear16[(cg += wp[1]) & mask]; + op[2] = ToLinear16[(cb += wp[2]) & mask]; + } + } + else if (stride == 4) + { + op[0] = ToLinear16[cr = (wp[0] & mask)]; + op[1] = ToLinear16[cg = (wp[1] & mask)]; + op[2] = ToLinear16[cb = (wp[2] & mask)]; + op[3] = ToLinear16[ca = (wp[3] & mask)]; + n -= 4; + while (n > 0) + { + wp += 4; + op += 4; + n -= 4; + op[0] = ToLinear16[(cr += wp[0]) & mask]; + op[1] = ToLinear16[(cg += wp[1]) & mask]; + op[2] = ToLinear16[(cb += wp[2]) & mask]; + op[3] = ToLinear16[(ca += wp[3]) & mask]; + } + } + else + { + REPEAT(stride, *op = ToLinear16[*wp & mask]; wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; *op = ToLinear16[*wp & mask]; + wp++; op++) + n -= stride; + } + } } } -/* +/* * Returns the log encoded 11-bit values with the horizontal * differencing undone. */ -static void -horizontalAccumulate11(uint16_t *wp, int n, int stride, uint16_t *op) +static void horizontalAccumulate11(uint16_t *wp, int n, int stride, + uint16_t *op) { register unsigned int cr, cg, cb, ca, mask; - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - op[0] = wp[0]; op[1] = wp[1]; op[2] = wp[2]; - cr = wp[0]; cg = wp[1]; cb = wp[2]; - n -= 3; - while (n > 0) { - wp += 3; - op += 3; - n -= 3; - op[0] = (uint16_t)((cr += wp[0]) & mask); - op[1] = (uint16_t)((cg += wp[1]) & mask); - op[2] = (uint16_t)((cb += wp[2]) & mask); - } - } else if (stride == 4) { - op[0] = wp[0]; op[1] = wp[1]; - op[2] = wp[2]; op[3] = wp[3]; - cr = wp[0]; cg = wp[1]; cb = wp[2]; ca = wp[3]; - n -= 4; - while (n > 0) { - wp += 4; - op += 4; - n -= 4; - op[0] = (uint16_t)((cr += wp[0]) & mask); - op[1] = (uint16_t)((cg += wp[1]) & mask); - op[2] = (uint16_t)((cb += wp[2]) & mask); - op[3] = (uint16_t)((ca += wp[3]) & mask); - } - } else { - REPEAT(stride, *op = *wp&mask; wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; *op = *wp&mask; wp++; op++) - n -= stride; - } - } + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + op[0] = wp[0]; + op[1] = wp[1]; + op[2] = wp[2]; + cr = wp[0]; + cg = wp[1]; + cb = wp[2]; + n -= 3; + while (n > 0) + { + wp += 3; + op += 3; + n -= 3; + op[0] = (uint16_t)((cr += wp[0]) & mask); + op[1] = (uint16_t)((cg += wp[1]) & mask); + op[2] = (uint16_t)((cb += wp[2]) & mask); + } + } + else if (stride == 4) + { + op[0] = wp[0]; + op[1] = wp[1]; + op[2] = wp[2]; + op[3] = wp[3]; + cr = wp[0]; + cg = wp[1]; + cb = wp[2]; + ca = wp[3]; + n -= 4; + while (n > 0) + { + wp += 4; + op += 4; + n -= 4; + op[0] = (uint16_t)((cr += wp[0]) & mask); + op[1] = (uint16_t)((cg += wp[1]) & mask); + op[2] = (uint16_t)((cb += wp[2]) & mask); + op[3] = (uint16_t)((ca += wp[3]) & mask); + } + } + else + { + REPEAT(stride, *op = *wp & mask; wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; *op = *wp & mask; wp++; op++) + n -= stride; + } + } } } -static void -horizontalAccumulate8(uint16_t *wp, int n, int stride, unsigned char *op, - unsigned char *ToLinear8) +static void horizontalAccumulate8(uint16_t *wp, int n, int stride, + unsigned char *op, unsigned char *ToLinear8) { - register unsigned int cr, cg, cb, ca, mask; - - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - op[0] = ToLinear8[cr = (wp[0] & mask)]; - op[1] = ToLinear8[cg = (wp[1] & mask)]; - op[2] = ToLinear8[cb = (wp[2] & mask)]; - n -= 3; - while (n > 0) { - n -= 3; - wp += 3; - op += 3; - op[0] = ToLinear8[(cr += wp[0]) & mask]; - op[1] = ToLinear8[(cg += wp[1]) & mask]; - op[2] = ToLinear8[(cb += wp[2]) & mask]; - } - } else if (stride == 4) { - op[0] = ToLinear8[cr = (wp[0] & mask)]; - op[1] = ToLinear8[cg = (wp[1] & mask)]; - op[2] = ToLinear8[cb = (wp[2] & mask)]; - op[3] = ToLinear8[ca = (wp[3] & mask)]; - n -= 4; - while (n > 0) { - n -= 4; - wp += 4; - op += 4; - op[0] = ToLinear8[(cr += wp[0]) & mask]; - op[1] = ToLinear8[(cg += wp[1]) & mask]; - op[2] = ToLinear8[(cb += wp[2]) & mask]; - op[3] = ToLinear8[(ca += wp[3]) & mask]; - } - } else { - REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) - n -= stride; - } - } + register unsigned int cr, cg, cb, ca, mask; + + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + op[0] = ToLinear8[cr = (wp[0] & mask)]; + op[1] = ToLinear8[cg = (wp[1] & mask)]; + op[2] = ToLinear8[cb = (wp[2] & mask)]; + n -= 3; + while (n > 0) + { + n -= 3; + wp += 3; + op += 3; + op[0] = ToLinear8[(cr += wp[0]) & mask]; + op[1] = ToLinear8[(cg += wp[1]) & mask]; + op[2] = ToLinear8[(cb += wp[2]) & mask]; + } + } + else if (stride == 4) + { + op[0] = ToLinear8[cr = (wp[0] & mask)]; + op[1] = ToLinear8[cg = (wp[1] & mask)]; + op[2] = ToLinear8[cb = (wp[2] & mask)]; + op[3] = ToLinear8[ca = (wp[3] & mask)]; + n -= 4; + while (n > 0) + { + n -= 4; + wp += 4; + op += 4; + op[0] = ToLinear8[(cr += wp[0]) & mask]; + op[1] = ToLinear8[(cg += wp[1]) & mask]; + op[2] = ToLinear8[(cb += wp[2]) & mask]; + op[3] = ToLinear8[(ca += wp[3]) & mask]; + } + } + else + { + REPEAT(stride, *op = ToLinear8[*wp & mask]; wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask]; + wp++; op++) + n -= stride; + } + } } } - -static void -horizontalAccumulate8abgr(uint16_t *wp, int n, int stride, unsigned char *op, - unsigned char *ToLinear8) +static void horizontalAccumulate8abgr(uint16_t *wp, int n, int stride, + unsigned char *op, + unsigned char *ToLinear8) { - register unsigned int cr, cg, cb, ca, mask; - register unsigned char t0, t1, t2, t3; - - if (n >= stride) { - mask = CODE_MASK; - if (stride == 3) { - op[0] = 0; - t1 = ToLinear8[cb = (wp[2] & mask)]; - t2 = ToLinear8[cg = (wp[1] & mask)]; - t3 = ToLinear8[cr = (wp[0] & mask)]; - op[1] = t1; - op[2] = t2; - op[3] = t3; - n -= 3; - while (n > 0) { - n -= 3; - wp += 3; - op += 4; - op[0] = 0; - t1 = ToLinear8[(cb += wp[2]) & mask]; - t2 = ToLinear8[(cg += wp[1]) & mask]; - t3 = ToLinear8[(cr += wp[0]) & mask]; - op[1] = t1; - op[2] = t2; - op[3] = t3; - } - } else if (stride == 4) { - t0 = ToLinear8[ca = (wp[3] & mask)]; - t1 = ToLinear8[cb = (wp[2] & mask)]; - t2 = ToLinear8[cg = (wp[1] & mask)]; - t3 = ToLinear8[cr = (wp[0] & mask)]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - n -= 4; - while (n > 0) { - n -= 4; - wp += 4; - op += 4; - t0 = ToLinear8[(ca += wp[3]) & mask]; - t1 = ToLinear8[(cb += wp[2]) & mask]; - t2 = ToLinear8[(cg += wp[1]) & mask]; - t3 = ToLinear8[(cr += wp[0]) & mask]; - op[0] = t0; - op[1] = t1; - op[2] = t2; - op[3] = t3; - } - } else { - REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++) - n -= stride; - } - } + register unsigned int cr, cg, cb, ca, mask; + register unsigned char t0, t1, t2, t3; + + if (n >= stride) + { + mask = CODE_MASK; + if (stride == 3) + { + op[0] = 0; + t1 = ToLinear8[cb = (wp[2] & mask)]; + t2 = ToLinear8[cg = (wp[1] & mask)]; + t3 = ToLinear8[cr = (wp[0] & mask)]; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 3; + while (n > 0) + { + n -= 3; + wp += 3; + op += 4; + op[0] = 0; + t1 = ToLinear8[(cb += wp[2]) & mask]; + t2 = ToLinear8[(cg += wp[1]) & mask]; + t3 = ToLinear8[(cr += wp[0]) & mask]; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } + else if (stride == 4) + { + t0 = ToLinear8[ca = (wp[3] & mask)]; + t1 = ToLinear8[cb = (wp[2] & mask)]; + t2 = ToLinear8[cg = (wp[1] & mask)]; + t3 = ToLinear8[cr = (wp[0] & mask)]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + n -= 4; + while (n > 0) + { + n -= 4; + wp += 4; + op += 4; + t0 = ToLinear8[(ca += wp[3]) & mask]; + t1 = ToLinear8[(cb += wp[2]) & mask]; + t2 = ToLinear8[(cg += wp[1]) & mask]; + t3 = ToLinear8[(cr += wp[0]) & mask]; + op[0] = t0; + op[1] = t1; + op[2] = t2; + op[3] = t3; + } + } + else + { + REPEAT(stride, *op = ToLinear8[*wp & mask]; wp++; op++) + n -= stride; + while (n > 0) + { + REPEAT(stride, wp[stride] += *wp; *op = ToLinear8[*wp & mask]; + wp++; op++) + n -= stride; + } + } } } @@ -454,110 +520,121 @@ horizontalAccumulate8abgr(uint16_t *wp, int n, int stride, unsigned char *op, * State block for each open TIFF * file using PixarLog compression/decompression. */ -typedef struct { - TIFFPredictorState predict; - z_stream stream; - tmsize_t tbuf_size; /* only set/used on reading for now */ - uint16_t *tbuf; - uint16_t stride; - int state; - int user_datafmt; - int quality; +typedef struct +{ + TIFFPredictorState predict; + z_stream stream; + tmsize_t tbuf_size; /* only set/used on reading for now */ + uint16_t *tbuf; + uint16_t stride; + int state; + int user_datafmt; + int quality; #define PLSTATE_INIT 1 - TIFFVSetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVSetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + + float *ToLinearF; + uint16_t *ToLinear16; + unsigned char *ToLinear8; + uint16_t *FromLT2; + uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */ + uint16_t *From8; - float *ToLinearF; - uint16_t *ToLinear16; - unsigned char *ToLinear8; - uint16_t *FromLT2; - uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */ - uint16_t *From8; - } PixarLogState; -static int -PixarLogMakeTables(TIFF* tif, PixarLogState *sp) +static int PixarLogMakeTables(TIFF *tif, PixarLogState *sp) { -/* - * We make several tables here to convert between various external - * representations (float, 16-bit, and 8-bit) and the internal - * 11-bit companded representation. The 11-bit representation has two - * distinct regions. A linear bottom end up through .018316 in steps - * of about .000073, and a region of constant ratio up to about 25. - * These floating point numbers are stored in the main table ToLinearF. - * All other tables are derived from this one. The tables (and the - * ratios) are continuous at the internal seam. - */ + /* + * We make several tables here to convert between various external + * representations (float, 16-bit, and 8-bit) and the internal + * 11-bit companded representation. The 11-bit representation has two + * distinct regions. A linear bottom end up through .018316 in steps + * of about .000073, and a region of constant ratio up to about 25. + * These floating point numbers are stored in the main table ToLinearF. + * All other tables are derived from this one. The tables (and the + * ratios) are continuous at the internal seam. + */ - int nlin, lt2size; - int i, j; - double b, c, linstep, v; + int nlin, lt2size; + int i, j; + double b, c, linstep, v; float *ToLinearF; uint16_t *ToLinear16; unsigned char *ToLinear8; - uint16_t *FromLT2; - uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */ - uint16_t *From8; - - c = log(RATIO); - nlin = (int)(1./c); /* nlin must be an integer */ - c = 1./nlin; - b = exp(-c*ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */ - linstep = b*c*exp(1.); - - LogK1 = (float)(1./c); /* if (v >= 2) token = k1*log(v*k2) */ - LogK2 = (float)(1./b); - lt2size = (int)(2./linstep) + 1; + uint16_t *FromLT2; + uint16_t *From14; /* Really for 16-bit data, but we shift down 2 */ + uint16_t *From8; + + c = log(RATIO); + nlin = (int)(1. / c); /* nlin must be an integer */ + c = 1. / nlin; + b = exp(-c * ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */ + linstep = b * c * exp(1.); + + LogK1 = (float)(1. / c); /* if (v >= 2) token = k1*log(v*k2) */ + LogK2 = (float)(1. / b); + lt2size = (int)(2. / linstep) + 1; FromLT2 = (uint16_t *)_TIFFmallocExt(tif, lt2size * sizeof(uint16_t)); From14 = (uint16_t *)_TIFFmallocExt(tif, 16384 * sizeof(uint16_t)); From8 = (uint16_t *)_TIFFmallocExt(tif, 256 * sizeof(uint16_t)); ToLinearF = (float *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(float)); ToLinear16 = (uint16_t *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(uint16_t)); - ToLinear8 = (unsigned char *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(unsigned char)); - if (FromLT2 == NULL || From14 == NULL || From8 == NULL || - ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) { - if (FromLT2) _TIFFfreeExt(tif, FromLT2); - if (From14) _TIFFfreeExt(tif, From14); - if (From8) _TIFFfreeExt(tif, From8); - if (ToLinearF) _TIFFfreeExt(tif, ToLinearF); - if (ToLinear16) _TIFFfreeExt(tif, ToLinear16); - if (ToLinear8) _TIFFfreeExt(tif, ToLinear8); - sp->FromLT2 = NULL; - sp->From14 = NULL; - sp->From8 = NULL; - sp->ToLinearF = NULL; - sp->ToLinear16 = NULL; - sp->ToLinear8 = NULL; - return 0; + ToLinear8 = + (unsigned char *)_TIFFmallocExt(tif, TSIZEP1 * sizeof(unsigned char)); + if (FromLT2 == NULL || From14 == NULL || From8 == NULL || + ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) + { + if (FromLT2) + _TIFFfreeExt(tif, FromLT2); + if (From14) + _TIFFfreeExt(tif, From14); + if (From8) + _TIFFfreeExt(tif, From8); + if (ToLinearF) + _TIFFfreeExt(tif, ToLinearF); + if (ToLinear16) + _TIFFfreeExt(tif, ToLinear16); + if (ToLinear8) + _TIFFfreeExt(tif, ToLinear8); + sp->FromLT2 = NULL; + sp->From14 = NULL; + sp->From8 = NULL; + sp->ToLinearF = NULL; + sp->ToLinear16 = NULL; + sp->ToLinear8 = NULL; + return 0; } j = 0; - for (i = 0; i < nlin; i++) { - v = i * linstep; - ToLinearF[j++] = (float)v; + for (i = 0; i < nlin; i++) + { + v = i * linstep; + ToLinearF[j++] = (float)v; } for (i = nlin; i < TSIZE; i++) - ToLinearF[j++] = (float)(b*exp(c*i)); + ToLinearF[j++] = (float)(b * exp(c * i)); ToLinearF[2048] = ToLinearF[2047]; - for (i = 0; i < TSIZEP1; i++) { - v = ToLinearF[i]*65535.0 + 0.5; - ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16_t)v; - v = ToLinearF[i]*255.0 + 0.5; - ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v; + for (i = 0; i < TSIZEP1; i++) + { + v = ToLinearF[i] * 65535.0 + 0.5; + ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16_t)v; + v = ToLinearF[i] * 255.0 + 0.5; + ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v; } j = 0; - for (i = 0; i < lt2size; i++) { - if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1]) - j++; - FromLT2[i] = (uint16_t)j; + for (i = 0; i < lt2size; i++) + { + if ((i * linstep) * (i * linstep) > ToLinearF[j] * ToLinearF[j + 1]) + j++; + FromLT2[i] = (uint16_t)j; } /* @@ -566,20 +643,22 @@ PixarLogMakeTables(TIFF* tif, PixarLogState *sp) * saves a little table space. */ j = 0; - for (i = 0; i < 16384; i++) { - while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1]) - j++; - From14[i] = (uint16_t)j; + for (i = 0; i < 16384; i++) + { + while ((i / 16383.) * (i / 16383.) > ToLinearF[j] * ToLinearF[j + 1]) + j++; + From14[i] = (uint16_t)j; } j = 0; - for (i = 0; i < 256; i++) { - while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1]) - j++; - From8[i] = (uint16_t)j; + for (i = 0; i < 256; i++) + { + while ((i / 255.) * (i / 255.) > ToLinearF[j] * ToLinearF[j + 1]) + j++; + From8[i] = (uint16_t)j; } - Fltsize = (float)(lt2size/2); + Fltsize = (float)(lt2size / 2); sp->ToLinearF = ToLinearF; sp->ToLinear16 = ToLinear16; @@ -591,622 +670,727 @@ PixarLogMakeTables(TIFF* tif, PixarLogState *sp) return 1; } -#define DecoderState(tif) ((PixarLogState*) (tif)->tif_data) -#define EncoderState(tif) ((PixarLogState*) (tif)->tif_data) +#define DecoderState(tif) ((PixarLogState *)(tif)->tif_data) +#define EncoderState(tif) ((PixarLogState *)(tif)->tif_data) -static int PixarLogEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s); -static int PixarLogDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s); +static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -#define PIXARLOGDATAFMT_UNKNOWN -1 +#define PIXARLOGDATAFMT_UNKNOWN -1 -static int -PixarLogGuessDataFmt(TIFFDirectory *td) +static int PixarLogGuessDataFmt(TIFFDirectory *td) { - int guess = PIXARLOGDATAFMT_UNKNOWN; - int format = td->td_sampleformat; - - /* If the user didn't tell us his datafmt, - * take our best guess from the bitspersample. - */ - switch (td->td_bitspersample) { - case 32: - if (format == SAMPLEFORMAT_IEEEFP) - guess = PIXARLOGDATAFMT_FLOAT; - break; - case 16: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) - guess = PIXARLOGDATAFMT_16BIT; - break; - case 12: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT) - guess = PIXARLOGDATAFMT_12BITPICIO; - break; - case 11: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) - guess = PIXARLOGDATAFMT_11BITLOG; - break; - case 8: - if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) - guess = PIXARLOGDATAFMT_8BIT; - break; - } - - return guess; + int guess = PIXARLOGDATAFMT_UNKNOWN; + int format = td->td_sampleformat; + + /* If the user didn't tell us his datafmt, + * take our best guess from the bitspersample. + */ + switch (td->td_bitspersample) + { + case 32: + if (format == SAMPLEFORMAT_IEEEFP) + guess = PIXARLOGDATAFMT_FLOAT; + break; + case 16: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_16BIT; + break; + case 12: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT) + guess = PIXARLOGDATAFMT_12BITPICIO; + break; + case 11: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_11BITLOG; + break; + case 8: + if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT) + guess = PIXARLOGDATAFMT_8BIT; + break; + } + + return guess; } -static tmsize_t -multiply_ms(tmsize_t m1, tmsize_t m2) +static tmsize_t multiply_ms(tmsize_t m1, tmsize_t m2) { - return _TIFFMultiplySSize(NULL, m1, m2, NULL); + return _TIFFMultiplySSize(NULL, m1, m2, NULL); } -static tmsize_t -add_ms(tmsize_t m1, tmsize_t m2) +static tmsize_t add_ms(tmsize_t m1, tmsize_t m2) { - assert(m1 >= 0 && m2 >= 0); - /* if either input is zero, assume overflow already occurred */ - if (m1 == 0 || m2 == 0) - return 0; - else if (m1 > TIFF_TMSIZE_T_MAX - m2) - return 0; - - return m1 + m2; + assert(m1 >= 0 && m2 >= 0); + /* if either input is zero, assume overflow already occurred */ + if (m1 == 0 || m2 == 0) + return 0; + else if (m1 > TIFF_TMSIZE_T_MAX - m2) + return 0; + + return m1 + m2; } -static int -PixarLogFixupTags(TIFF* tif) +static int PixarLogFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } -static int -PixarLogSetupDecode(TIFF* tif) +static int PixarLogSetupDecode(TIFF *tif) { - static const char module[] = "PixarLogSetupDecode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState* sp = DecoderState(tif); - tmsize_t tbuf_size; - uint32_t strip_height; - - assert(sp != NULL); - - /* This function can possibly be called several times by */ - /* PredictorSetupDecode() if this function succeeds but */ - /* PredictorSetup() fails */ - if( (sp->state & PLSTATE_INIT) != 0 ) - return 1; - - strip_height = td->td_rowsperstrip; - if( strip_height > td->td_imagelength ) - strip_height = td->td_imagelength; - - /* Make sure no byte swapping happens on the data - * after decompression. */ - tif->tif_postdecode = _TIFFNoPostDecode; - - /* for some reason, we can't do this in TIFFInitPixarLog */ - - sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? - td->td_samplesperpixel : 1); - tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), - strip_height), sizeof(uint16_t)); - /* add one more stride in case input ends mid-stride */ - tbuf_size = add_ms(tbuf_size, sizeof(uint16_t) * sp->stride); - if (tbuf_size == 0) - return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ - sp->tbuf = (uint16_t *) _TIFFmallocExt(tif, tbuf_size); - if (sp->tbuf == NULL) - return (0); - sp->tbuf_size = tbuf_size; - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) - sp->user_datafmt = PixarLogGuessDataFmt(td); - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { - _TIFFfreeExt(tif, sp->tbuf); - sp->tbuf = NULL; - sp->tbuf_size = 0; - TIFFErrorExtR(tif, module, - "PixarLog compression can't handle bits depth/data format combination (depth: %"PRIu16")", - td->td_bitspersample); - return (0); - } - - if (inflateInit(&sp->stream) != Z_OK) { - _TIFFfreeExt(tif, sp->tbuf); - sp->tbuf = NULL; - sp->tbuf_size = 0; - TIFFErrorExtR(tif, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } else { - sp->state |= PLSTATE_INIT; - return (1); - } + static const char module[] = "PixarLogSetupDecode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = DecoderState(tif); + tmsize_t tbuf_size; + uint32_t strip_height; + + assert(sp != NULL); + + /* This function can possibly be called several times by */ + /* PredictorSetupDecode() if this function succeeds but */ + /* PredictorSetup() fails */ + if ((sp->state & PLSTATE_INIT) != 0) + return 1; + + strip_height = td->td_rowsperstrip; + if (strip_height > td->td_imagelength) + strip_height = td->td_imagelength; + + /* Make sure no byte swapping happens on the data + * after decompression. */ + tif->tif_postdecode = _TIFFNoPostDecode; + + /* for some reason, we can't do this in TIFFInitPixarLog */ + + sp->stride = + (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel + : 1); + tbuf_size = multiply_ms( + multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), strip_height), + sizeof(uint16_t)); + /* add one more stride in case input ends mid-stride */ + tbuf_size = add_ms(tbuf_size, sizeof(uint16_t) * sp->stride); + if (tbuf_size == 0) + return (0); /* TODO: this is an error return without error report + through TIFFErrorExt */ + sp->tbuf = (uint16_t *)_TIFFmallocExt(tif, tbuf_size); + if (sp->tbuf == NULL) + return (0); + sp->tbuf_size = tbuf_size; + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + sp->user_datafmt = PixarLogGuessDataFmt(td); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + { + _TIFFfreeExt(tif, sp->tbuf); + sp->tbuf = NULL; + sp->tbuf_size = 0; + TIFFErrorExtR(tif, module, + "PixarLog compression can't handle bits depth/data " + "format combination (depth: %" PRIu16 ")", + td->td_bitspersample); + return (0); + } + + if (inflateInit(&sp->stream) != Z_OK) + { + _TIFFfreeExt(tif, sp->tbuf); + sp->tbuf = NULL; + sp->tbuf_size = 0; + TIFFErrorExtR(tif, module, "%s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + else + { + sp->state |= PLSTATE_INIT; + return (1); + } } /* * Setup state for decoding a strip. */ -static int -PixarLogPreDecode(TIFF* tif, uint16_t s) +static int PixarLogPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "PixarLogPreDecode"; - PixarLogState* sp = DecoderState(tif); - - (void) s; - assert(sp != NULL); - sp->stream.next_in = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_in = (uInt) tif->tif_rawcc; - if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) - { - TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); - return (0); - } - return (inflateReset(&sp->stream) == Z_OK); + static const char module[] = "PixarLogPreDecode"; + PixarLogState *sp = DecoderState(tif); + + (void)s; + assert(sp != NULL); + sp->stream.next_in = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_in = (uInt)tif->tif_rawcc; + if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc) + { + TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); + return (0); + } + return (inflateReset(&sp->stream) == Z_OK); } -static int -PixarLogDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) +static int PixarLogDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "PixarLogDecode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState* sp = DecoderState(tif); - tmsize_t i; - tmsize_t nsamples; - int llen; - uint16_t *up; - - switch (sp->user_datafmt) { - case PIXARLOGDATAFMT_FLOAT: - nsamples = occ / sizeof(float); /* XXX float == 32 bits */ - break; - case PIXARLOGDATAFMT_16BIT: - case PIXARLOGDATAFMT_12BITPICIO: - case PIXARLOGDATAFMT_11BITLOG: - nsamples = occ / sizeof(uint16_t); /* XXX uint16_t == 16 bits */ - break; - case PIXARLOGDATAFMT_8BIT: - case PIXARLOGDATAFMT_8BITABGR: - nsamples = occ; - break; - default: - TIFFErrorExtR(tif, module, - "%"PRIu16" bit input not supported in PixarLog", - td->td_bitspersample); - return 0; - } - - llen = sp->stride * td->td_imagewidth; - - (void) s; - assert(sp != NULL); - - sp->stream.next_in = tif->tif_rawcp; - sp->stream.avail_in = (uInt) tif->tif_rawcc; - - sp->stream.next_out = (unsigned char *) sp->tbuf; - assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16_t)); - if (sp->stream.avail_out != nsamples * sizeof(uint16_t)) - { - TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); - return (0); - } - /* Check that we will not fill more than what was allocated */ - if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size) - { - TIFFErrorExtR(tif, module, "sp->stream.avail_out > sp->tbuf_size"); - return (0); - } - do { - int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); - if (state == Z_STREAM_END) { - break; /* XXX */ - } - if (state == Z_DATA_ERROR) { - TIFFErrorExtR(tif, module, - "Decoding error at scanline %"PRIu32", %s", - tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - if (state != Z_OK) { - TIFFErrorExtR(tif, module, "ZLib error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - } while (sp->stream.avail_out > 0); - - /* hopefully, we got all the bytes we needed */ - if (sp->stream.avail_out != 0) { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %"PRIu32" (short %u bytes)", - tif->tif_row, sp->stream.avail_out); - return (0); - } - - tif->tif_rawcp = sp->stream.next_in; - tif->tif_rawcc = sp->stream.avail_in; - - up = sp->tbuf; - /* Swap bytes in the data if from a different endian machine. */ - if (tif->tif_flags & TIFF_SWAB) - TIFFSwabArrayOfShort(up, nsamples); - - /* - * if llen is not an exact multiple of nsamples, the decode operation - * may overflow the output buffer, so truncate it enough to prevent - * that but still salvage as much data as possible. - */ - if (nsamples % llen) { - TIFFWarningExtR(tif, module, - "stride %d is not a multiple of sample count, " - "%"TIFF_SSIZE_FORMAT", data truncated.", llen, nsamples); - nsamples -= nsamples % llen; - } - - for (i = 0; i < nsamples; i += llen, up += llen) { - switch (sp->user_datafmt) { - case PIXARLOGDATAFMT_FLOAT: - horizontalAccumulateF(up, llen, sp->stride, - (float *)op, sp->ToLinearF); - op += llen * sizeof(float); - break; - case PIXARLOGDATAFMT_16BIT: - horizontalAccumulate16(up, llen, sp->stride, - (uint16_t *)op, sp->ToLinear16); - op += llen * sizeof(uint16_t); - break; - case PIXARLOGDATAFMT_12BITPICIO: - horizontalAccumulate12(up, llen, sp->stride, - (int16_t *)op, sp->ToLinearF); - op += llen * sizeof(int16_t); - break; - case PIXARLOGDATAFMT_11BITLOG: - horizontalAccumulate11(up, llen, sp->stride, - (uint16_t *)op); - op += llen * sizeof(uint16_t); - break; - case PIXARLOGDATAFMT_8BIT: - horizontalAccumulate8(up, llen, sp->stride, - (unsigned char *)op, sp->ToLinear8); - op += llen * sizeof(unsigned char); - break; - case PIXARLOGDATAFMT_8BITABGR: - horizontalAccumulate8abgr(up, llen, sp->stride, - (unsigned char *)op, sp->ToLinear8); - op += llen * sizeof(unsigned char); - break; - default: - TIFFErrorExtR(tif, module, - "Unsupported bits/sample: %"PRIu16, - td->td_bitspersample); - return (0); - } - } - - return (1); + static const char module[] = "PixarLogDecode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = DecoderState(tif); + tmsize_t i; + tmsize_t nsamples; + int llen; + uint16_t *up; + + switch (sp->user_datafmt) + { + case PIXARLOGDATAFMT_FLOAT: + nsamples = occ / sizeof(float); /* XXX float == 32 bits */ + break; + case PIXARLOGDATAFMT_16BIT: + case PIXARLOGDATAFMT_12BITPICIO: + case PIXARLOGDATAFMT_11BITLOG: + nsamples = occ / sizeof(uint16_t); /* XXX uint16_t == 16 bits */ + break; + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + nsamples = occ; + break; + default: + TIFFErrorExtR(tif, module, + "%" PRIu16 " bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + + llen = sp->stride * td->td_imagewidth; + + (void)s; + assert(sp != NULL); + + sp->stream.next_in = tif->tif_rawcp; + sp->stream.avail_in = (uInt)tif->tif_rawcc; + + sp->stream.next_out = (unsigned char *)sp->tbuf; + assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_out = (uInt)(nsamples * sizeof(uint16_t)); + if (sp->stream.avail_out != nsamples * sizeof(uint16_t)) + { + TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); + return (0); + } + /* Check that we will not fill more than what was allocated */ + if ((tmsize_t)sp->stream.avail_out > sp->tbuf_size) + { + TIFFErrorExtR(tif, module, "sp->stream.avail_out > sp->tbuf_size"); + return (0); + } + do + { + int state = inflate(&sp->stream, Z_PARTIAL_FLUSH); + if (state == Z_STREAM_END) + { + break; /* XXX */ + } + if (state == Z_DATA_ERROR) + { + TIFFErrorExtR( + tif, module, "Decoding error at scanline %" PRIu32 ", %s", + tif->tif_row, sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + if (state != Z_OK) + { + TIFFErrorExtR(tif, module, "ZLib error: %s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + } while (sp->stream.avail_out > 0); + + /* hopefully, we got all the bytes we needed */ + if (sp->stream.avail_out != 0) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %" PRIu32 + " (short %u bytes)", + tif->tif_row, sp->stream.avail_out); + return (0); + } + + tif->tif_rawcp = sp->stream.next_in; + tif->tif_rawcc = sp->stream.avail_in; + + up = sp->tbuf; + /* Swap bytes in the data if from a different endian machine. */ + if (tif->tif_flags & TIFF_SWAB) + TIFFSwabArrayOfShort(up, nsamples); + + /* + * if llen is not an exact multiple of nsamples, the decode operation + * may overflow the output buffer, so truncate it enough to prevent + * that but still salvage as much data as possible. + */ + if (nsamples % llen) + { + TIFFWarningExtR(tif, module, + "stride %d is not a multiple of sample count, " + "%" TIFF_SSIZE_FORMAT ", data truncated.", + llen, nsamples); + nsamples -= nsamples % llen; + } + + for (i = 0; i < nsamples; i += llen, up += llen) + { + switch (sp->user_datafmt) + { + case PIXARLOGDATAFMT_FLOAT: + horizontalAccumulateF(up, llen, sp->stride, (float *)op, + sp->ToLinearF); + op += llen * sizeof(float); + break; + case PIXARLOGDATAFMT_16BIT: + horizontalAccumulate16(up, llen, sp->stride, (uint16_t *)op, + sp->ToLinear16); + op += llen * sizeof(uint16_t); + break; + case PIXARLOGDATAFMT_12BITPICIO: + horizontalAccumulate12(up, llen, sp->stride, (int16_t *)op, + sp->ToLinearF); + op += llen * sizeof(int16_t); + break; + case PIXARLOGDATAFMT_11BITLOG: + horizontalAccumulate11(up, llen, sp->stride, (uint16_t *)op); + op += llen * sizeof(uint16_t); + break; + case PIXARLOGDATAFMT_8BIT: + horizontalAccumulate8(up, llen, sp->stride, (unsigned char *)op, + sp->ToLinear8); + op += llen * sizeof(unsigned char); + break; + case PIXARLOGDATAFMT_8BITABGR: + horizontalAccumulate8abgr(up, llen, sp->stride, + (unsigned char *)op, sp->ToLinear8); + op += llen * sizeof(unsigned char); + break; + default: + TIFFErrorExtR(tif, module, "Unsupported bits/sample: %" PRIu16, + td->td_bitspersample); + return (0); + } + } + + return (1); } -static int -PixarLogSetupEncode(TIFF* tif) +static int PixarLogSetupEncode(TIFF *tif) { - static const char module[] = "PixarLogSetupEncode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState* sp = EncoderState(tif); - tmsize_t tbuf_size; - - assert(sp != NULL); - - /* for some reason, we can't do this in TIFFInitPixarLog */ - - sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? - td->td_samplesperpixel : 1); - tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), - td->td_rowsperstrip), sizeof(uint16_t)); - if (tbuf_size == 0) - return (0); /* TODO: this is an error return without error report through TIFFErrorExt */ - sp->tbuf = (uint16_t *) _TIFFmallocExt(tif, tbuf_size); - if (sp->tbuf == NULL) - return (0); - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) - sp->user_datafmt = PixarLogGuessDataFmt(td); - if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { - TIFFErrorExtR(tif, module, "PixarLog compression can't handle %"PRIu16" bit linear encodings", td->td_bitspersample); - return (0); - } - - if (deflateInit(&sp->stream, sp->quality) != Z_OK) { - TIFFErrorExtR(tif, module, "%s", sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } else { - sp->state |= PLSTATE_INIT; - return (1); - } + static const char module[] = "PixarLogSetupEncode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = EncoderState(tif); + tmsize_t tbuf_size; + + assert(sp != NULL); + + /* for some reason, we can't do this in TIFFInitPixarLog */ + + sp->stride = + (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel + : 1); + tbuf_size = + multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth), + td->td_rowsperstrip), + sizeof(uint16_t)); + if (tbuf_size == 0) + return (0); /* TODO: this is an error return without error report + through TIFFErrorExt */ + sp->tbuf = (uint16_t *)_TIFFmallocExt(tif, tbuf_size); + if (sp->tbuf == NULL) + return (0); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + sp->user_datafmt = PixarLogGuessDataFmt(td); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + { + TIFFErrorExtR(tif, module, + "PixarLog compression can't handle %" PRIu16 + " bit linear encodings", + td->td_bitspersample); + return (0); + } + + if (deflateInit(&sp->stream, sp->quality) != Z_OK) + { + TIFFErrorExtR(tif, module, "%s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + else + { + sp->state |= PLSTATE_INIT; + return (1); + } } /* * Reset encoding state at the start of a strip. */ -static int -PixarLogPreEncode(TIFF* tif, uint16_t s) +static int PixarLogPreEncode(TIFF *tif, uint16_t s) { - static const char module[] = "PixarLogPreEncode"; - PixarLogState *sp = EncoderState(tif); - - (void) s; - assert(sp != NULL); - sp->stream.next_out = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_out = (uInt)tif->tif_rawdatasize; - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) - { - TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); - return (0); - } - return (deflateReset(&sp->stream) == Z_OK); + static const char module[] = "PixarLogPreEncode"; + PixarLogState *sp = EncoderState(tif); + + (void)s; + assert(sp != NULL); + sp->stream.next_out = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_out = (uInt)tif->tif_rawdatasize; + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); + return (0); + } + return (deflateReset(&sp->stream) == Z_OK); } -static void -horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp, uint16_t *FromLT2) +static void horizontalDifferenceF(float *ip, int n, int stride, uint16_t *wp, + uint16_t *FromLT2) { int32_t r1, g1, b1, a1, r2, g2, b2, a2, mask; float fltsize = Fltsize; -#define CLAMP(v) ( (v<(float)0.) ? 0 \ - : (v<(float)2.) ? FromLT2[(int)(v*fltsize)] \ - : (v>(float)24.2) ? 2047 \ - : LogK1*log(v*LogK2) + 0.5 ) +#define CLAMP(v) \ + ((v < (float)0.) ? 0 \ + : (v < (float)2.) ? FromLT2[(int)(v * fltsize)] \ + : (v > (float)24.2) ? 2047 \ + : LogK1 * log(v * LogK2) + 0.5) mask = CODE_MASK; - if (n >= stride) { - if (stride == 3) { - r2 = wp[0] = (uint16_t) CLAMP(ip[0]); - g2 = wp[1] = (uint16_t) CLAMP(ip[1]); - b2 = wp[2] = (uint16_t) CLAMP(ip[2]); - n -= 3; - while (n > 0) { - n -= 3; - wp += 3; - ip += 3; - r1 = (int32_t) CLAMP(ip[0]); wp[0] = (uint16_t)((r1 - r2) & mask); r2 = r1; - g1 = (int32_t) CLAMP(ip[1]); wp[1] = (uint16_t)((g1 - g2) & mask); g2 = g1; - b1 = (int32_t) CLAMP(ip[2]); wp[2] = (uint16_t)((b1 - b2) & mask); b2 = b1; - } - } else if (stride == 4) { - r2 = wp[0] = (uint16_t) CLAMP(ip[0]); - g2 = wp[1] = (uint16_t) CLAMP(ip[1]); - b2 = wp[2] = (uint16_t) CLAMP(ip[2]); - a2 = wp[3] = (uint16_t) CLAMP(ip[3]); - n -= 4; - while (n > 0) { - n -= 4; - wp += 4; - ip += 4; - r1 = (int32_t) CLAMP(ip[0]); wp[0] = (uint16_t)((r1 - r2) & mask); r2 = r1; - g1 = (int32_t) CLAMP(ip[1]); wp[1] = (uint16_t)((g1 - g2) & mask); g2 = g1; - b1 = (int32_t) CLAMP(ip[2]); wp[2] = (uint16_t)((b1 - b2) & mask); b2 = b1; - a1 = (int32_t) CLAMP(ip[3]); wp[3] = (uint16_t)((a1 - a2) & mask); a2 = a1; - } - } else { - REPEAT(stride, wp[0] = (uint16_t) CLAMP(ip[0]); wp++; ip++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[0] = (uint16_t)(((int32_t)CLAMP(ip[0]) - (int32_t)CLAMP(ip[-stride])) & mask); - wp++; ip++) + if (n >= stride) + { + if (stride == 3) + { + r2 = wp[0] = (uint16_t)CLAMP(ip[0]); + g2 = wp[1] = (uint16_t)CLAMP(ip[1]); + b2 = wp[2] = (uint16_t)CLAMP(ip[2]); + n -= 3; + while (n > 0) + { + n -= 3; + wp += 3; + ip += 3; + r1 = (int32_t)CLAMP(ip[0]); + wp[0] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = (int32_t)CLAMP(ip[1]); + wp[1] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = (int32_t)CLAMP(ip[2]); + wp[2] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + } + } + else if (stride == 4) + { + r2 = wp[0] = (uint16_t)CLAMP(ip[0]); + g2 = wp[1] = (uint16_t)CLAMP(ip[1]); + b2 = wp[2] = (uint16_t)CLAMP(ip[2]); + a2 = wp[3] = (uint16_t)CLAMP(ip[3]); + n -= 4; + while (n > 0) + { + n -= 4; + wp += 4; + ip += 4; + r1 = (int32_t)CLAMP(ip[0]); + wp[0] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = (int32_t)CLAMP(ip[1]); + wp[1] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = (int32_t)CLAMP(ip[2]); + wp[2] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + a1 = (int32_t)CLAMP(ip[3]); + wp[3] = (uint16_t)((a1 - a2) & mask); + a2 = a1; + } + } + else + { + REPEAT(stride, wp[0] = (uint16_t)CLAMP(ip[0]); wp++; ip++) n -= stride; + while (n > 0) + { + REPEAT(stride, + wp[0] = (uint16_t)(((int32_t)CLAMP(ip[0]) - + (int32_t)CLAMP(ip[-stride])) & + mask); + wp++; ip++) + n -= stride; + } } - } } } -static void -horizontalDifference16(unsigned short *ip, int n, int stride, - unsigned short *wp, uint16_t *From14) +static void horizontalDifference16(unsigned short *ip, int n, int stride, + unsigned short *wp, uint16_t *From14) { - register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + register int r1, g1, b1, a1, r2, g2, b2, a2, mask; /* assumption is unsigned pixel values */ -#undef CLAMP -#define CLAMP(v) From14[(v) >> 2] +#undef CLAMP +#define CLAMP(v) From14[(v) >> 2] mask = CODE_MASK; - if (n >= stride) { - if (stride == 3) { - r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); - n -= 3; - while (n > 0) { - n -= 3; - wp += 3; - ip += 3; - r1 = CLAMP(ip[0]); wp[0] = (uint16_t)((r1 - r2) & mask); r2 = r1; - g1 = CLAMP(ip[1]); wp[1] = (uint16_t)((g1 - g2) & mask); g2 = g1; - b1 = CLAMP(ip[2]); wp[2] = (uint16_t)((b1 - b2) & mask); b2 = b1; - } - } else if (stride == 4) { - r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); - n -= 4; - while (n > 0) { - n -= 4; - wp += 4; - ip += 4; - r1 = CLAMP(ip[0]); wp[0] = (uint16_t)((r1 - r2) & mask); r2 = r1; - g1 = CLAMP(ip[1]); wp[1] = (uint16_t)((g1 - g2) & mask); g2 = g1; - b1 = CLAMP(ip[2]); wp[2] = (uint16_t)((b1 - b2) & mask); b2 = b1; - a1 = CLAMP(ip[3]); wp[3] = (uint16_t)((a1 - a2) & mask); a2 = a1; - } - } else { - REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) & mask); - wp++; ip++) + if (n >= stride) + { + if (stride == 3) + { + r2 = wp[0] = CLAMP(ip[0]); + g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + n -= 3; + while (n > 0) + { + n -= 3; + wp += 3; + ip += 3; + r1 = CLAMP(ip[0]); + wp[0] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = CLAMP(ip[1]); + wp[1] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = CLAMP(ip[2]); + wp[2] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + } + } + else if (stride == 4) + { + r2 = wp[0] = CLAMP(ip[0]); + g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + a2 = wp[3] = CLAMP(ip[3]); + n -= 4; + while (n > 0) + { + n -= 4; + wp += 4; + ip += 4; + r1 = CLAMP(ip[0]); + wp[0] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = CLAMP(ip[1]); + wp[1] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = CLAMP(ip[2]); + wp[2] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + a1 = CLAMP(ip[3]); + wp[3] = (uint16_t)((a1 - a2) & mask); + a2 = a1; + } + } + else + { + REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) n -= stride; + while (n > 0) + { + REPEAT(stride, + wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) & + mask); + wp++; ip++) + n -= stride; + } } - } } } - -static void -horizontalDifference8(unsigned char *ip, int n, int stride, - unsigned short *wp, uint16_t *From8) +static void horizontalDifference8(unsigned char *ip, int n, int stride, + unsigned short *wp, uint16_t *From8) { - register int r1, g1, b1, a1, r2, g2, b2, a2, mask; + register int r1, g1, b1, a1, r2, g2, b2, a2, mask; -#undef CLAMP -#define CLAMP(v) (From8[(v)]) +#undef CLAMP +#define CLAMP(v) (From8[(v)]) mask = CODE_MASK; - if (n >= stride) { - if (stride == 3) { - r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); - n -= 3; - while (n > 0) { - n -= 3; - r1 = CLAMP(ip[3]); wp[3] = (uint16_t)((r1 - r2) & mask); r2 = r1; - g1 = CLAMP(ip[4]); wp[4] = (uint16_t)((g1 - g2) & mask); g2 = g1; - b1 = CLAMP(ip[5]); wp[5] = (uint16_t)((b1 - b2) & mask); b2 = b1; - wp += 3; - ip += 3; - } - } else if (stride == 4) { - r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]); - b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]); - n -= 4; - while (n > 0) { - n -= 4; - r1 = CLAMP(ip[4]); wp[4] = (uint16_t)((r1 - r2) & mask); r2 = r1; - g1 = CLAMP(ip[5]); wp[5] = (uint16_t)((g1 - g2) & mask); g2 = g1; - b1 = CLAMP(ip[6]); wp[6] = (uint16_t)((b1 - b2) & mask); b2 = b1; - a1 = CLAMP(ip[7]); wp[7] = (uint16_t)((a1 - a2) & mask); a2 = a1; - wp += 4; - ip += 4; - } - } else { - REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) - n -= stride; - while (n > 0) { - REPEAT(stride, - wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) & mask); - wp++; ip++) + if (n >= stride) + { + if (stride == 3) + { + r2 = wp[0] = CLAMP(ip[0]); + g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + n -= 3; + while (n > 0) + { + n -= 3; + r1 = CLAMP(ip[3]); + wp[3] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = CLAMP(ip[4]); + wp[4] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = CLAMP(ip[5]); + wp[5] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + wp += 3; + ip += 3; + } + } + else if (stride == 4) + { + r2 = wp[0] = CLAMP(ip[0]); + g2 = wp[1] = CLAMP(ip[1]); + b2 = wp[2] = CLAMP(ip[2]); + a2 = wp[3] = CLAMP(ip[3]); + n -= 4; + while (n > 0) + { + n -= 4; + r1 = CLAMP(ip[4]); + wp[4] = (uint16_t)((r1 - r2) & mask); + r2 = r1; + g1 = CLAMP(ip[5]); + wp[5] = (uint16_t)((g1 - g2) & mask); + g2 = g1; + b1 = CLAMP(ip[6]); + wp[6] = (uint16_t)((b1 - b2) & mask); + b2 = b1; + a1 = CLAMP(ip[7]); + wp[7] = (uint16_t)((a1 - a2) & mask); + a2 = a1; + wp += 4; + ip += 4; + } + } + else + { + REPEAT(stride, wp[0] = CLAMP(ip[0]); wp++; ip++) n -= stride; + while (n > 0) + { + REPEAT(stride, + wp[0] = (uint16_t)((CLAMP(ip[0]) - CLAMP(ip[-stride])) & + mask); + wp++; ip++) + n -= stride; + } } } - } } /* * Encode a chunk of pixels. */ -static int -PixarLogEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int PixarLogEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "PixarLogEncode"; - TIFFDirectory *td = &tif->tif_dir; - PixarLogState *sp = EncoderState(tif); - tmsize_t i; - tmsize_t n; - int llen; - unsigned short * up; - - (void) s; - - switch (sp->user_datafmt) { - case PIXARLOGDATAFMT_FLOAT: - n = cc / sizeof(float); /* XXX float == 32 bits */ - break; - case PIXARLOGDATAFMT_16BIT: - case PIXARLOGDATAFMT_12BITPICIO: - case PIXARLOGDATAFMT_11BITLOG: - n = cc / sizeof(uint16_t); /* XXX uint16_t == 16 bits */ - break; - case PIXARLOGDATAFMT_8BIT: - case PIXARLOGDATAFMT_8BITABGR: - n = cc; - break; - default: - TIFFErrorExtR(tif, module, - "%"PRIu16" bit input not supported in PixarLog", - td->td_bitspersample); - return 0; - } - - llen = sp->stride * td->td_imagewidth; + static const char module[] = "PixarLogEncode"; + TIFFDirectory *td = &tif->tif_dir; + PixarLogState *sp = EncoderState(tif); + tmsize_t i; + tmsize_t n; + int llen; + unsigned short *up; + + (void)s; + + switch (sp->user_datafmt) + { + case PIXARLOGDATAFMT_FLOAT: + n = cc / sizeof(float); /* XXX float == 32 bits */ + break; + case PIXARLOGDATAFMT_16BIT: + case PIXARLOGDATAFMT_12BITPICIO: + case PIXARLOGDATAFMT_11BITLOG: + n = cc / sizeof(uint16_t); /* XXX uint16_t == 16 bits */ + break; + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + n = cc; + break; + default: + TIFFErrorExtR(tif, module, + "%" PRIu16 " bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + + llen = sp->stride * td->td_imagewidth; /* Check against the number of elements (of size uint16_t) of sp->tbuf */ - if( n > ((tmsize_t)td->td_rowsperstrip * llen) ) + if (n > ((tmsize_t)td->td_rowsperstrip * llen)) { - TIFFErrorExtR(tif, module, - "Too many input bytes provided"); + TIFFErrorExtR(tif, module, "Too many input bytes provided"); return 0; } - for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) { - switch (sp->user_datafmt) { - case PIXARLOGDATAFMT_FLOAT: - horizontalDifferenceF((float *)bp, llen, - sp->stride, up, sp->FromLT2); - bp += llen * sizeof(float); - break; - case PIXARLOGDATAFMT_16BIT: - horizontalDifference16((uint16_t *)bp, llen, - sp->stride, up, sp->From14); - bp += llen * sizeof(uint16_t); - break; - case PIXARLOGDATAFMT_8BIT: - horizontalDifference8((unsigned char *)bp, llen, - sp->stride, up, sp->From8); - bp += llen * sizeof(unsigned char); - break; - default: - TIFFErrorExtR(tif, module, - "%"PRIu16" bit input not supported in PixarLog", - td->td_bitspersample); - return 0; - } - } - - sp->stream.next_in = (unsigned char *) sp->tbuf; - assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_in = (uInt) (n * sizeof(uint16_t)); - if ((sp->stream.avail_in / sizeof(uint16_t)) != (uInt) n) - { - TIFFErrorExtR(tif, module, - "ZLib cannot deal with buffers this size"); - return (0); - } - - do { - if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { - TIFFErrorExtR(tif, module, "Encoder error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - if (sp->stream.avail_out == 0) { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ - } - } while (sp->stream.avail_in > 0); - return (1); + for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) + { + switch (sp->user_datafmt) + { + case PIXARLOGDATAFMT_FLOAT: + horizontalDifferenceF((float *)bp, llen, sp->stride, up, + sp->FromLT2); + bp += llen * sizeof(float); + break; + case PIXARLOGDATAFMT_16BIT: + horizontalDifference16((uint16_t *)bp, llen, sp->stride, up, + sp->From14); + bp += llen * sizeof(uint16_t); + break; + case PIXARLOGDATAFMT_8BIT: + horizontalDifference8((unsigned char *)bp, llen, sp->stride, up, + sp->From8); + bp += llen * sizeof(unsigned char); + break; + default: + TIFFErrorExtR(tif, module, + "%" PRIu16 " bit input not supported in PixarLog", + td->td_bitspersample); + return 0; + } + } + + sp->stream.next_in = (unsigned char *)sp->tbuf; + assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_in = (uInt)(n * sizeof(uint16_t)); + if ((sp->stream.avail_in / sizeof(uint16_t)) != (uInt)n) + { + TIFFErrorExtR(tif, module, "ZLib cannot deal with buffers this size"); + return (0); + } + + do + { + if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) + { + TIFFErrorExtR(tif, module, "Encoder error: %s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + if (sp->stream.avail_out == 0) + { + tif->tif_rawcc = tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = + (uInt)tif + ->tif_rawdatasize; /* this is a safe typecast, as check is + made already in PixarLogPreEncode */ + } + } while (sp->stream.avail_in > 0); + return (1); } /* @@ -1214,258 +1398,273 @@ PixarLogEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) * string and tacking on an End Of Information code. */ -static int -PixarLogPostEncode(TIFF* tif) +static int PixarLogPostEncode(TIFF *tif) { - static const char module[] = "PixarLogPostEncode"; - PixarLogState *sp = EncoderState(tif); - int state; - - sp->stream.avail_in = 0; - - do { - state = deflate(&sp->stream, Z_FINISH); - switch (state) { - case Z_STREAM_END: - case Z_OK: - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) { - tif->tif_rawcc = - tif->tif_rawdatasize - sp->stream.avail_out; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */ - } - break; - default: - TIFFErrorExtR(tif, module, "ZLib error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - } while (state != Z_STREAM_END); - return (1); + static const char module[] = "PixarLogPostEncode"; + PixarLogState *sp = EncoderState(tif); + int state; + + sp->stream.avail_in = 0; + + do + { + state = deflate(&sp->stream, Z_FINISH); + switch (state) + { + case Z_STREAM_END: + case Z_OK: + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = + (uInt)tif->tif_rawdatasize; /* this is a safe typecast, + as check is made already + in PixarLogPreEncode */ + } + break; + default: + TIFFErrorExtR(tif, module, "ZLib error: %s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + } while (state != Z_STREAM_END); + return (1); } -static void -PixarLogClose(TIFF* tif) +static void PixarLogClose(TIFF *tif) { - PixarLogState* sp = (PixarLogState*) tif->tif_data; - TIFFDirectory *td = &tif->tif_dir; - - assert(sp != 0); - /* In a really sneaky (and really incorrect, and untruthful, and - * troublesome, and error-prone) maneuver that completely goes against - * the spirit of TIFF, and breaks TIFF, on close, we covertly - * modify both bitspersample and sampleformat in the directory to - * indicate 8-bit linear. This way, the decode "just works" even for - * readers that don't know about PixarLog, or how to set - * the PIXARLOGDATFMT pseudo-tag. - */ - - if (sp->state&PLSTATE_INIT) { - /* We test the state to avoid an issue such as in - * http://bugzilla.maptools.org/show_bug.cgi?id=2604 - * What appends in that case is that the bitspersample is 1 and - * a TransferFunction is set. The size of the TransferFunction - * depends on 1<<bitspersample. So if we increase it, an access - * out of the buffer will happen at directory flushing. - * Another option would be to clear those targs. - */ - td->td_bitspersample = 8; - td->td_sampleformat = SAMPLEFORMAT_UINT; - } + PixarLogState *sp = (PixarLogState *)tif->tif_data; + TIFFDirectory *td = &tif->tif_dir; + + assert(sp != 0); + /* In a really sneaky (and really incorrect, and untruthful, and + * troublesome, and error-prone) maneuver that completely goes against + * the spirit of TIFF, and breaks TIFF, on close, we covertly + * modify both bitspersample and sampleformat in the directory to + * indicate 8-bit linear. This way, the decode "just works" even for + * readers that don't know about PixarLog, or how to set + * the PIXARLOGDATFMT pseudo-tag. + */ + + if (sp->state & PLSTATE_INIT) + { + /* We test the state to avoid an issue such as in + * http://bugzilla.maptools.org/show_bug.cgi?id=2604 + * What appends in that case is that the bitspersample is 1 and + * a TransferFunction is set. The size of the TransferFunction + * depends on 1<<bitspersample. So if we increase it, an access + * out of the buffer will happen at directory flushing. + * Another option would be to clear those targs. + */ + td->td_bitspersample = 8; + td->td_sampleformat = SAMPLEFORMAT_UINT; + } } -static void -PixarLogCleanup(TIFF* tif) +static void PixarLogCleanup(TIFF *tif) { - PixarLogState* sp = (PixarLogState*) tif->tif_data; - - assert(sp != 0); - - (void)TIFFPredictorCleanup(tif); - - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - - if (sp->FromLT2) _TIFFfreeExt(tif, sp->FromLT2); - if (sp->From14) _TIFFfreeExt(tif, sp->From14); - if (sp->From8) _TIFFfreeExt(tif, sp->From8); - if (sp->ToLinearF) _TIFFfreeExt(tif, sp->ToLinearF); - if (sp->ToLinear16) _TIFFfreeExt(tif, sp->ToLinear16); - if (sp->ToLinear8) _TIFFfreeExt(tif, sp->ToLinear8); - if (sp->state&PLSTATE_INIT) { - if (tif->tif_mode == O_RDONLY) - inflateEnd(&sp->stream); - else - deflateEnd(&sp->stream); - } - if (sp->tbuf) - _TIFFfreeExt(tif, sp->tbuf); - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; - - _TIFFSetDefaultCompressionState(tif); + PixarLogState *sp = (PixarLogState *)tif->tif_data; + + assert(sp != 0); + + (void)TIFFPredictorCleanup(tif); + + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + + if (sp->FromLT2) + _TIFFfreeExt(tif, sp->FromLT2); + if (sp->From14) + _TIFFfreeExt(tif, sp->From14); + if (sp->From8) + _TIFFfreeExt(tif, sp->From8); + if (sp->ToLinearF) + _TIFFfreeExt(tif, sp->ToLinearF); + if (sp->ToLinear16) + _TIFFfreeExt(tif, sp->ToLinear16); + if (sp->ToLinear8) + _TIFFfreeExt(tif, sp->ToLinear8); + if (sp->state & PLSTATE_INIT) + { + if (tif->tif_mode == O_RDONLY) + inflateEnd(&sp->stream); + else + deflateEnd(&sp->stream); + } + if (sp->tbuf) + _TIFFfreeExt(tif, sp->tbuf); + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; + + _TIFFSetDefaultCompressionState(tif); } -static int -PixarLogVSetField(TIFF* tif, uint32_t tag, va_list ap) +static int PixarLogVSetField(TIFF *tif, uint32_t tag, va_list ap) { static const char module[] = "PixarLogVSetField"; PixarLogState *sp = (PixarLogState *)tif->tif_data; int result; - switch (tag) { - case TIFFTAG_PIXARLOGQUALITY: - sp->quality = (int) va_arg(ap, int); - if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) { - if (deflateParams(&sp->stream, - sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) { - TIFFErrorExtR(tif, module, "ZLib error: %s", - sp->stream.msg ? sp->stream.msg : "(null)"); - return (0); - } - } - return (1); - case TIFFTAG_PIXARLOGDATAFMT: - sp->user_datafmt = (int) va_arg(ap, int); - /* Tweak the TIFF header so that the rest of libtiff knows what - * size of data will be passed between app and library, and - * assume that the app knows what it is doing and is not - * confused by these header manipulations... - */ - switch (sp->user_datafmt) { - case PIXARLOGDATAFMT_8BIT: - case PIXARLOGDATAFMT_8BITABGR: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); - break; - case PIXARLOGDATAFMT_11BITLOG: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); - break; - case PIXARLOGDATAFMT_12BITPICIO: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); - break; - case PIXARLOGDATAFMT_16BIT: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); - break; - case PIXARLOGDATAFMT_FLOAT: - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32); - TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); - break; - } - /* - * Must recalculate sizes should bits/sample change. - */ - tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); - tif->tif_scanlinesize = TIFFScanlineSize(tif); - result = 1; /* NB: pseudo tag */ - break; - default: - result = (*sp->vsetparent)(tif, tag, ap); + switch (tag) + { + case TIFFTAG_PIXARLOGQUALITY: + sp->quality = (int)va_arg(ap, int); + if (tif->tif_mode != O_RDONLY && (sp->state & PLSTATE_INIT)) + { + if (deflateParams(&sp->stream, sp->quality, + Z_DEFAULT_STRATEGY) != Z_OK) + { + TIFFErrorExtR(tif, module, "ZLib error: %s", + sp->stream.msg ? sp->stream.msg : "(null)"); + return (0); + } + } + return (1); + case TIFFTAG_PIXARLOGDATAFMT: + sp->user_datafmt = (int)va_arg(ap, int); + /* Tweak the TIFF header so that the rest of libtiff knows what + * size of data will be passed between app and library, and + * assume that the app knows what it is doing and is not + * confused by these header manipulations... + */ + switch (sp->user_datafmt) + { + case PIXARLOGDATAFMT_8BIT: + case PIXARLOGDATAFMT_8BITABGR: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_11BITLOG: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_12BITPICIO: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); + break; + case PIXARLOGDATAFMT_16BIT: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + break; + case PIXARLOGDATAFMT_FLOAT: + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32); + TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, + SAMPLEFORMAT_IEEEFP); + break; + } + /* + * Must recalculate sizes should bits/sample change. + */ + tif->tif_tilesize = + isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1); + tif->tif_scanlinesize = TIFFScanlineSize(tif); + result = 1; /* NB: pseudo tag */ + break; + default: + result = (*sp->vsetparent)(tif, tag, ap); } return (result); } -static int -PixarLogVGetField(TIFF* tif, uint32_t tag, va_list ap) +static int PixarLogVGetField(TIFF *tif, uint32_t tag, va_list ap) { PixarLogState *sp = (PixarLogState *)tif->tif_data; - switch (tag) { - case TIFFTAG_PIXARLOGQUALITY: - *va_arg(ap, int*) = sp->quality; - break; - case TIFFTAG_PIXARLOGDATAFMT: - *va_arg(ap, int*) = sp->user_datafmt; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); + switch (tag) + { + case TIFFTAG_PIXARLOGQUALITY: + *va_arg(ap, int *) = sp->quality; + break; + case TIFFTAG_PIXARLOGDATAFMT: + *va_arg(ap, int *) = sp->user_datafmt; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); } return (1); } static const TIFFField pixarlogFields[] = { - {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, - {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL} -}; + {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}, + {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}}; -int -TIFFInitPixarLog(TIFF* tif, int scheme) +int TIFFInitPixarLog(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitPixarLog"; - - PixarLogState* sp; - - (void)scheme; - assert(scheme == COMPRESSION_PIXARLOG); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, pixarlogFields, - TIFFArrayCount(pixarlogFields))) { - TIFFErrorExtR(tif, module, - "Merging PixarLog codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t*) _TIFFmallocExt(tif, sizeof (PixarLogState)); - if (tif->tif_data == NULL) - goto bad; - sp = (PixarLogState*) tif->tif_data; - _TIFFmemset(sp, 0, sizeof (*sp)); - sp->stream.data_type = Z_BINARY; - sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = PixarLogFixupTags; - tif->tif_setupdecode = PixarLogSetupDecode; - tif->tif_predecode = PixarLogPreDecode; - tif->tif_decoderow = PixarLogDecode; - tif->tif_decodestrip = PixarLogDecode; - tif->tif_decodetile = PixarLogDecode; - tif->tif_setupencode = PixarLogSetupEncode; - tif->tif_preencode = PixarLogPreEncode; - tif->tif_postencode = PixarLogPostEncode; - tif->tif_encoderow = PixarLogEncode; - tif->tif_encodestrip = PixarLogEncode; - tif->tif_encodetile = PixarLogEncode; - tif->tif_close = PixarLogClose; - tif->tif_cleanup = PixarLogCleanup; - - /* Override SetField so we can handle our private pseudo-tag */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */ - sp->state = 0; - - /* we don't wish to use the predictor, - * the default is none, which predictor value 1 - */ - (void) TIFFPredictorInit(tif); - - /* - * build the companding tables - */ - PixarLogMakeTables(tif, sp); - - return (1); + static const char module[] = "TIFFInitPixarLog"; + + PixarLogState *sp; + + (void)scheme; + assert(scheme == COMPRESSION_PIXARLOG); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, pixarlogFields, TIFFArrayCount(pixarlogFields))) + { + TIFFErrorExtR(tif, module, + "Merging PixarLog codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(PixarLogState)); + if (tif->tif_data == NULL) + goto bad; + sp = (PixarLogState *)tif->tif_data; + _TIFFmemset(sp, 0, sizeof(*sp)); + sp->stream.data_type = Z_BINARY; + sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = PixarLogFixupTags; + tif->tif_setupdecode = PixarLogSetupDecode; + tif->tif_predecode = PixarLogPreDecode; + tif->tif_decoderow = PixarLogDecode; + tif->tif_decodestrip = PixarLogDecode; + tif->tif_decodetile = PixarLogDecode; + tif->tif_setupencode = PixarLogSetupEncode; + tif->tif_preencode = PixarLogPreEncode; + tif->tif_postencode = PixarLogPostEncode; + tif->tif_encoderow = PixarLogEncode; + tif->tif_encodestrip = PixarLogEncode; + tif->tif_encodetile = PixarLogEncode; + tif->tif_close = PixarLogClose; + tif->tif_cleanup = PixarLogCleanup; + + /* Override SetField so we can handle our private pseudo-tag */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */ + sp->state = 0; + + /* we don't wish to use the predictor, + * the default is none, which predictor value 1 + */ + (void)TIFFPredictorInit(tif); + + /* + * build the companding tables + */ + PixarLogMakeTables(tif, sp); + + return (1); bad: - TIFFErrorExtR(tif, module, - "No space for PixarLog state block"); - return (0); + TIFFErrorExtR(tif, module, "No space for PixarLog state block"); + return (0); } #endif /* PIXARLOG_SUPPORT */ diff --git a/libtiff/tif_predict.c b/libtiff/tif_predict.c index d041c8ff..386b5fe8 100644 --- a/libtiff/tif_predict.c +++ b/libtiff/tif_predict.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -27,259 +27,309 @@ * * Predictor Tag Support (used by multiple codecs). */ -#include "tiffiop.h" #include "tif_predict.h" +#include "tiffiop.h" -#define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data) - -static int horAcc8(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int horAcc16(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int horAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int horAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int swabHorAcc16(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int swabHorAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int swabHorAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int horDiff8(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int horDiff16(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int horDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int horDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int swabHorDiff16(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int swabHorDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int swabHorDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int fpAcc(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int fpDiff(TIFF* tif, uint8_t* cp0, tmsize_t cc); -static int PredictorDecodeRow(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s); -static int PredictorDecodeTile(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s); -static int PredictorEncodeRow(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s); -static int PredictorEncodeTile(TIFF* tif, uint8_t* bp0, tmsize_t cc0, uint16_t s); - -static int -PredictorSetup(TIFF* tif) +#define PredictorState(tif) ((TIFFPredictorState *)(tif)->tif_data) + +static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc); +static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0, + uint16_t s); +static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0, + uint16_t s); +static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0, + uint16_t s); + +static int PredictorSetup(TIFF *tif) { - static const char module[] = "PredictorSetup"; - - TIFFPredictorState* sp = PredictorState(tif); - TIFFDirectory* td = &tif->tif_dir; - - switch (sp->predictor) /* no differencing */ - { - case PREDICTOR_NONE: - return 1; - case PREDICTOR_HORIZONTAL: - if (td->td_bitspersample != 8 - && td->td_bitspersample != 16 - && td->td_bitspersample != 32 - && td->td_bitspersample != 64) { - TIFFErrorExtR(tif, module, - "Horizontal differencing \"Predictor\" not supported with %"PRIu16"-bit samples", - td->td_bitspersample); - return 0; - } - break; - case PREDICTOR_FLOATINGPOINT: - if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) { - TIFFErrorExtR(tif, module, - "Floating point \"Predictor\" not supported with %"PRIu16" data format", - td->td_sampleformat); - return 0; - } - if (td->td_bitspersample != 16 - && td->td_bitspersample != 24 - && td->td_bitspersample != 32 - && td->td_bitspersample != 64) { /* Should 64 be allowed? */ - TIFFErrorExtR(tif, module, - "Floating point \"Predictor\" not supported with %"PRIu16"-bit samples", - td->td_bitspersample); - return 0; - } - break; - default: - TIFFErrorExtR(tif, module, - "\"Predictor\" value %d not supported", - sp->predictor); - return 0; - } - sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? - td->td_samplesperpixel : 1); - /* - * Calculate the scanline/tile-width size in bytes. - */ - if (isTiled(tif)) - sp->rowsize = TIFFTileRowSize(tif); - else - sp->rowsize = TIFFScanlineSize(tif); - if (sp->rowsize == 0) - return 0; - - return 1; + static const char module[] = "PredictorSetup"; + + TIFFPredictorState *sp = PredictorState(tif); + TIFFDirectory *td = &tif->tif_dir; + + switch (sp->predictor) /* no differencing */ + { + case PREDICTOR_NONE: + return 1; + case PREDICTOR_HORIZONTAL: + if (td->td_bitspersample != 8 && td->td_bitspersample != 16 && + td->td_bitspersample != 32 && td->td_bitspersample != 64) + { + TIFFErrorExtR(tif, module, + "Horizontal differencing \"Predictor\" not " + "supported with %" PRIu16 "-bit samples", + td->td_bitspersample); + return 0; + } + break; + case PREDICTOR_FLOATINGPOINT: + if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) + { + TIFFErrorExtR( + tif, module, + "Floating point \"Predictor\" not supported with %" PRIu16 + " data format", + td->td_sampleformat); + return 0; + } + if (td->td_bitspersample != 16 && td->td_bitspersample != 24 && + td->td_bitspersample != 32 && td->td_bitspersample != 64) + { /* Should 64 be allowed? */ + TIFFErrorExtR( + tif, module, + "Floating point \"Predictor\" not supported with %" PRIu16 + "-bit samples", + td->td_bitspersample); + return 0; + } + break; + default: + TIFFErrorExtR(tif, module, "\"Predictor\" value %d not supported", + sp->predictor); + return 0; + } + sp->stride = + (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel + : 1); + /* + * Calculate the scanline/tile-width size in bytes. + */ + if (isTiled(tif)) + sp->rowsize = TIFFTileRowSize(tif); + else + sp->rowsize = TIFFScanlineSize(tif); + if (sp->rowsize == 0) + return 0; + + return 1; } -static int -PredictorSetupDecode(TIFF* tif) +static int PredictorSetupDecode(TIFF *tif) { - TIFFPredictorState* sp = PredictorState(tif); - TIFFDirectory* td = &tif->tif_dir; - - /* Note: when PredictorSetup() fails, the effets of setupdecode() */ - /* will not be "canceled" so setupdecode() might be robust to */ - /* be called several times. */ - if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) - return 0; - - if (sp->predictor == 2) { - switch (td->td_bitspersample) { - case 8: sp->decodepfunc = horAcc8; break; - case 16: sp->decodepfunc = horAcc16; break; - case 32: sp->decodepfunc = horAcc32; break; - case 64: sp->decodepfunc = horAcc64; break; - } - /* - * Override default decoding method with one that does the - * predictor stuff. - */ - if( tif->tif_decoderow != PredictorDecodeRow ) - { - sp->decoderow = tif->tif_decoderow; - tif->tif_decoderow = PredictorDecodeRow; - sp->decodestrip = tif->tif_decodestrip; - tif->tif_decodestrip = PredictorDecodeTile; - sp->decodetile = tif->tif_decodetile; - tif->tif_decodetile = PredictorDecodeTile; - } - - /* - * If the data is horizontally differenced 16-bit data that - * requires byte-swapping, then it must be byte swapped before - * the accumulation step. We do this with a special-purpose - * routine and override the normal post decoding logic that - * the library setup when the directory was read. - */ - if (tif->tif_flags & TIFF_SWAB) { - if (sp->decodepfunc == horAcc16) { - sp->decodepfunc = swabHorAcc16; - tif->tif_postdecode = _TIFFNoPostDecode; - } else if (sp->decodepfunc == horAcc32) { - sp->decodepfunc = swabHorAcc32; - tif->tif_postdecode = _TIFFNoPostDecode; - } else if (sp->decodepfunc == horAcc64) { - sp->decodepfunc = swabHorAcc64; - tif->tif_postdecode = _TIFFNoPostDecode; + TIFFPredictorState *sp = PredictorState(tif); + TIFFDirectory *td = &tif->tif_dir; + + /* Note: when PredictorSetup() fails, the effets of setupdecode() */ + /* will not be "canceled" so setupdecode() might be robust to */ + /* be called several times. */ + if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) + return 0; + + if (sp->predictor == 2) + { + switch (td->td_bitspersample) + { + case 8: + sp->decodepfunc = horAcc8; + break; + case 16: + sp->decodepfunc = horAcc16; + break; + case 32: + sp->decodepfunc = horAcc32; + break; + case 64: + sp->decodepfunc = horAcc64; + break; + } + /* + * Override default decoding method with one that does the + * predictor stuff. + */ + if (tif->tif_decoderow != PredictorDecodeRow) + { + sp->decoderow = tif->tif_decoderow; + tif->tif_decoderow = PredictorDecodeRow; + sp->decodestrip = tif->tif_decodestrip; + tif->tif_decodestrip = PredictorDecodeTile; + sp->decodetile = tif->tif_decodetile; + tif->tif_decodetile = PredictorDecodeTile; + } + + /* + * If the data is horizontally differenced 16-bit data that + * requires byte-swapping, then it must be byte swapped before + * the accumulation step. We do this with a special-purpose + * routine and override the normal post decoding logic that + * the library setup when the directory was read. + */ + if (tif->tif_flags & TIFF_SWAB) + { + if (sp->decodepfunc == horAcc16) + { + sp->decodepfunc = swabHorAcc16; + tif->tif_postdecode = _TIFFNoPostDecode; + } + else if (sp->decodepfunc == horAcc32) + { + sp->decodepfunc = swabHorAcc32; + tif->tif_postdecode = _TIFFNoPostDecode; } - } - } - - else if (sp->predictor == 3) { - sp->decodepfunc = fpAcc; - /* - * Override default decoding method with one that does the - * predictor stuff. - */ - if( tif->tif_decoderow != PredictorDecodeRow ) - { - sp->decoderow = tif->tif_decoderow; - tif->tif_decoderow = PredictorDecodeRow; - sp->decodestrip = tif->tif_decodestrip; - tif->tif_decodestrip = PredictorDecodeTile; - sp->decodetile = tif->tif_decodetile; - tif->tif_decodetile = PredictorDecodeTile; - } - /* - * The data should not be swapped outside of the floating - * point predictor, the accumulation routine should return - * byres in the native order. - */ - if (tif->tif_flags & TIFF_SWAB) { - tif->tif_postdecode = _TIFFNoPostDecode; - } - /* - * Allocate buffer to keep the decoded bytes before - * rearranging in the right order - */ - } - - return 1; + else if (sp->decodepfunc == horAcc64) + { + sp->decodepfunc = swabHorAcc64; + tif->tif_postdecode = _TIFFNoPostDecode; + } + } + } + + else if (sp->predictor == 3) + { + sp->decodepfunc = fpAcc; + /* + * Override default decoding method with one that does the + * predictor stuff. + */ + if (tif->tif_decoderow != PredictorDecodeRow) + { + sp->decoderow = tif->tif_decoderow; + tif->tif_decoderow = PredictorDecodeRow; + sp->decodestrip = tif->tif_decodestrip; + tif->tif_decodestrip = PredictorDecodeTile; + sp->decodetile = tif->tif_decodetile; + tif->tif_decodetile = PredictorDecodeTile; + } + /* + * The data should not be swapped outside of the floating + * point predictor, the accumulation routine should return + * byres in the native order. + */ + if (tif->tif_flags & TIFF_SWAB) + { + tif->tif_postdecode = _TIFFNoPostDecode; + } + /* + * Allocate buffer to keep the decoded bytes before + * rearranging in the right order + */ + } + + return 1; } -static int -PredictorSetupEncode(TIFF* tif) +static int PredictorSetupEncode(TIFF *tif) { - TIFFPredictorState* sp = PredictorState(tif); - TIFFDirectory* td = &tif->tif_dir; - - if (!(*sp->setupencode)(tif) || !PredictorSetup(tif)) - return 0; - - if (sp->predictor == 2) { - switch (td->td_bitspersample) { - case 8: sp->encodepfunc = horDiff8; break; - case 16: sp->encodepfunc = horDiff16; break; - case 32: sp->encodepfunc = horDiff32; break; - case 64: sp->encodepfunc = horDiff64; break; - } - /* - * Override default encoding method with one that does the - * predictor stuff. - */ - if( tif->tif_encoderow != PredictorEncodeRow ) - { - sp->encoderow = tif->tif_encoderow; - tif->tif_encoderow = PredictorEncodeRow; - sp->encodestrip = tif->tif_encodestrip; - tif->tif_encodestrip = PredictorEncodeTile; - sp->encodetile = tif->tif_encodetile; - tif->tif_encodetile = PredictorEncodeTile; - } - - /* - * If the data is horizontally differenced 16-bit data that - * requires byte-swapping, then it must be byte swapped after - * the differentiation step. We do this with a special-purpose - * routine and override the normal post decoding logic that - * the library setup when the directory was read. - */ - if (tif->tif_flags & TIFF_SWAB) { - if (sp->encodepfunc == horDiff16) { - sp->encodepfunc = swabHorDiff16; - tif->tif_postdecode = _TIFFNoPostDecode; - } else if (sp->encodepfunc == horDiff32) { - sp->encodepfunc = swabHorDiff32; - tif->tif_postdecode = _TIFFNoPostDecode; - } else if (sp->encodepfunc == horDiff64) { - sp->encodepfunc = swabHorDiff64; - tif->tif_postdecode = _TIFFNoPostDecode; - } - } + TIFFPredictorState *sp = PredictorState(tif); + TIFFDirectory *td = &tif->tif_dir; + + if (!(*sp->setupencode)(tif) || !PredictorSetup(tif)) + return 0; + + if (sp->predictor == 2) + { + switch (td->td_bitspersample) + { + case 8: + sp->encodepfunc = horDiff8; + break; + case 16: + sp->encodepfunc = horDiff16; + break; + case 32: + sp->encodepfunc = horDiff32; + break; + case 64: + sp->encodepfunc = horDiff64; + break; + } + /* + * Override default encoding method with one that does the + * predictor stuff. + */ + if (tif->tif_encoderow != PredictorEncodeRow) + { + sp->encoderow = tif->tif_encoderow; + tif->tif_encoderow = PredictorEncodeRow; + sp->encodestrip = tif->tif_encodestrip; + tif->tif_encodestrip = PredictorEncodeTile; + sp->encodetile = tif->tif_encodetile; + tif->tif_encodetile = PredictorEncodeTile; + } + + /* + * If the data is horizontally differenced 16-bit data that + * requires byte-swapping, then it must be byte swapped after + * the differentiation step. We do this with a special-purpose + * routine and override the normal post decoding logic that + * the library setup when the directory was read. + */ + if (tif->tif_flags & TIFF_SWAB) + { + if (sp->encodepfunc == horDiff16) + { + sp->encodepfunc = swabHorDiff16; + tif->tif_postdecode = _TIFFNoPostDecode; + } + else if (sp->encodepfunc == horDiff32) + { + sp->encodepfunc = swabHorDiff32; + tif->tif_postdecode = _TIFFNoPostDecode; + } + else if (sp->encodepfunc == horDiff64) + { + sp->encodepfunc = swabHorDiff64; + tif->tif_postdecode = _TIFFNoPostDecode; + } } + } + + else if (sp->predictor == 3) + { + sp->encodepfunc = fpDiff; + /* + * Override default encoding method with one that does the + * predictor stuff. + */ + if (tif->tif_encoderow != PredictorEncodeRow) + { + sp->encoderow = tif->tif_encoderow; + tif->tif_encoderow = PredictorEncodeRow; + sp->encodestrip = tif->tif_encodestrip; + tif->tif_encodestrip = PredictorEncodeTile; + sp->encodetile = tif->tif_encodetile; + tif->tif_encodetile = PredictorEncodeTile; + } + } - else if (sp->predictor == 3) { - sp->encodepfunc = fpDiff; - /* - * Override default encoding method with one that does the - * predictor stuff. - */ - if( tif->tif_encoderow != PredictorEncodeRow ) - { - sp->encoderow = tif->tif_encoderow; - tif->tif_encoderow = PredictorEncodeRow; - sp->encodestrip = tif->tif_encodestrip; - tif->tif_encodestrip = PredictorEncodeTile; - sp->encodetile = tif->tif_encodetile; - tif->tif_encodetile = PredictorEncodeTile; - } - } - - return 1; + return 1; } -#define REPEAT4(n, op) \ - switch (n) { \ - default: { \ - tmsize_t i; for (i = n-4; i > 0; i--) { op; } } /*-fallthrough*/ \ - case 4: op; /*-fallthrough*/ \ - case 3: op; /*-fallthrough*/ \ - case 2: op; /*-fallthrough*/ \ - case 1: op; /*-fallthrough*/ \ - case 0: ; \ +#define REPEAT4(n, op) \ + switch (n) \ + { \ + default: \ + { \ + tmsize_t i; \ + for (i = n - 4; i > 0; i--) \ + { \ + op; \ + } \ + } /*-fallthrough*/ \ + case 4: \ + op; /*-fallthrough*/ \ + case 3: \ + op; /*-fallthrough*/ \ + case 2: \ + op; /*-fallthrough*/ \ + case 1: \ + op; /*-fallthrough*/ \ + case 0:; \ } /* Remarks related to C standard compliance in all below functions : */ @@ -289,225 +339,236 @@ PredictorSetupEncode(TIFF* tif) /* as to make icc -check=conversions happy (not necessary by the standard) */ TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horAcc8(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int horAcc8(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; + tmsize_t stride = PredictorState(tif)->stride; - unsigned char* cp = (unsigned char*) cp0; - if((cc%stride)!=0) + unsigned char *cp = (unsigned char *)cp0; + if ((cc % stride) != 0) { - TIFFErrorExtR(tif, "horAcc8", - "%s", "(cc%stride)!=0"); + TIFFErrorExtR(tif, "horAcc8", "%s", "(cc%stride)!=0"); return 0; } - if (cc > stride) { - /* - * Pipeline the most common cases. - */ - if (stride == 3) { - unsigned int cr = cp[0]; - unsigned int cg = cp[1]; - unsigned int cb = cp[2]; - tmsize_t i = stride; - for ( ; i < cc; i += stride) { - cp[i+0] = (unsigned char) ((cr += cp[i+0]) & 0xff); - cp[i+1] = (unsigned char) ((cg += cp[i+1]) & 0xff); - cp[i+2] = (unsigned char) ((cb += cp[i+2]) & 0xff); - } - } else if (stride == 4) { - unsigned int cr = cp[0]; - unsigned int cg = cp[1]; - unsigned int cb = cp[2]; - unsigned int ca = cp[3]; - tmsize_t i = stride; - for ( ; i < cc; i += stride) { - cp[i+0] = (unsigned char) ((cr += cp[i+0]) & 0xff); - cp[i+1] = (unsigned char) ((cg += cp[i+1]) & 0xff); - cp[i+2] = (unsigned char) ((cb += cp[i+2]) & 0xff); - cp[i+3] = (unsigned char) ((ca += cp[i+3]) & 0xff); - } - } else { - cc -= stride; - do { - REPEAT4(stride, cp[stride] = - (unsigned char) ((cp[stride] + *cp) & 0xff); cp++) - cc -= stride; - } while (cc>0); - } - } - return 1; + if (cc > stride) + { + /* + * Pipeline the most common cases. + */ + if (stride == 3) + { + unsigned int cr = cp[0]; + unsigned int cg = cp[1]; + unsigned int cb = cp[2]; + tmsize_t i = stride; + for (; i < cc; i += stride) + { + cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff); + cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff); + cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff); + } + } + else if (stride == 4) + { + unsigned int cr = cp[0]; + unsigned int cg = cp[1]; + unsigned int cb = cp[2]; + unsigned int ca = cp[3]; + tmsize_t i = stride; + for (; i < cc; i += stride) + { + cp[i + 0] = (unsigned char)((cr += cp[i + 0]) & 0xff); + cp[i + 1] = (unsigned char)((cg += cp[i + 1]) & 0xff); + cp[i + 2] = (unsigned char)((cb += cp[i + 2]) & 0xff); + cp[i + 3] = (unsigned char)((ca += cp[i + 3]) & 0xff); + } + } + else + { + cc -= stride; + do + { + REPEAT4(stride, + cp[stride] = (unsigned char)((cp[stride] + *cp) & 0xff); + cp++) + cc -= stride; + } while (cc > 0); + } + } + return 1; } -static int -swabHorAcc16(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int swabHorAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - uint16_t* wp = (uint16_t*) cp0; - tmsize_t wc = cc / 2; + uint16_t *wp = (uint16_t *)cp0; + tmsize_t wc = cc / 2; - TIFFSwabArrayOfShort(wp, wc); - return horAcc16(tif, cp0, cc); + TIFFSwabArrayOfShort(wp, wc); + return horAcc16(tif, cp0, cc); } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horAcc16(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int horAcc16(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; - uint16_t* wp = (uint16_t*) cp0; - tmsize_t wc = cc / 2; + tmsize_t stride = PredictorState(tif)->stride; + uint16_t *wp = (uint16_t *)cp0; + tmsize_t wc = cc / 2; - if((cc%(2*stride))!=0) + if ((cc % (2 * stride)) != 0) { - TIFFErrorExtR(tif, "horAcc16", - "%s", "cc%(2*stride))!=0"); + TIFFErrorExtR(tif, "horAcc16", "%s", "cc%(2*stride))!=0"); return 0; } - if (wc > stride) { - wc -= stride; - do { - REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] + (unsigned int)wp[0]) & 0xffff); wp++) - wc -= stride; - } while (wc > 0); - } - return 1; + if (wc > stride) + { + wc -= stride; + do + { + REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] + + (unsigned int)wp[0]) & + 0xffff); + wp++) + wc -= stride; + } while (wc > 0); + } + return 1; } -static int -swabHorAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int swabHorAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - uint32_t* wp = (uint32_t*) cp0; - tmsize_t wc = cc / 4; + uint32_t *wp = (uint32_t *)cp0; + tmsize_t wc = cc / 4; - TIFFSwabArrayOfLong(wp, wc); - return horAcc32(tif, cp0, cc); + TIFFSwabArrayOfLong(wp, wc); + return horAcc32(tif, cp0, cc); } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horAcc32(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int horAcc32(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; - uint32_t* wp = (uint32_t*) cp0; - tmsize_t wc = cc / 4; + tmsize_t stride = PredictorState(tif)->stride; + uint32_t *wp = (uint32_t *)cp0; + tmsize_t wc = cc / 4; - if((cc%(4*stride))!=0) + if ((cc % (4 * stride)) != 0) { - TIFFErrorExtR(tif, "horAcc32", - "%s", "cc%(4*stride))!=0"); + TIFFErrorExtR(tif, "horAcc32", "%s", "cc%(4*stride))!=0"); return 0; } - if (wc > stride) { - wc -= stride; - do { - REPEAT4(stride, wp[stride] += wp[0]; wp++) - wc -= stride; - } while (wc > 0); - } - return 1; + if (wc > stride) + { + wc -= stride; + do + { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while (wc > 0); + } + return 1; } -static int -swabHorAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int swabHorAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - uint64_t* wp = (uint64_t*) cp0; - tmsize_t wc = cc / 8; + uint64_t *wp = (uint64_t *)cp0; + tmsize_t wc = cc / 8; - TIFFSwabArrayOfLong8(wp, wc); - return horAcc64(tif, cp0, cc); + TIFFSwabArrayOfLong8(wp, wc); + return horAcc64(tif, cp0, cc); } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horAcc64(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int horAcc64(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; - uint64_t* wp = (uint64_t*) cp0; - tmsize_t wc = cc / 8; - - if ((cc % (8 * stride)) != 0) - { - TIFFErrorExtR(tif, "horAcc64", - "%s", "cc%(8*stride))!=0"); - return 0; - } - - if (wc > stride) { - wc -= stride; - do { - REPEAT4(stride, wp[stride] += wp[0]; wp++) - wc -= stride; - } while (wc > 0); - } - return 1; + tmsize_t stride = PredictorState(tif)->stride; + uint64_t *wp = (uint64_t *)cp0; + tmsize_t wc = cc / 8; + + if ((cc % (8 * stride)) != 0) + { + TIFFErrorExtR(tif, "horAcc64", "%s", "cc%(8*stride))!=0"); + return 0; + } + + if (wc > stride) + { + wc -= stride; + do + { + REPEAT4(stride, wp[stride] += wp[0]; wp++) + wc -= stride; + } while (wc > 0); + } + return 1; } /* * Floating point predictor accumulation routine. */ -static int -fpAcc(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int fpAcc(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; - uint32_t bps = tif->tif_dir.td_bitspersample / 8; - tmsize_t wc = cc / bps; - tmsize_t count = cc; - uint8_t *cp = (uint8_t *) cp0; - uint8_t *tmp; - - if(cc%(bps*stride)!=0) + tmsize_t stride = PredictorState(tif)->stride; + uint32_t bps = tif->tif_dir.td_bitspersample / 8; + tmsize_t wc = cc / bps; + tmsize_t count = cc; + uint8_t *cp = (uint8_t *)cp0; + uint8_t *tmp; + + if (cc % (bps * stride) != 0) { - TIFFErrorExtR(tif, "fpAcc", - "%s", "cc%(bps*stride))!=0"); + TIFFErrorExtR(tif, "fpAcc", "%s", "cc%(bps*stride))!=0"); return 0; } tmp = (uint8_t *)_TIFFmallocExt(tif, cc); - if (!tmp) - return 0; - - while (count > stride) { - REPEAT4(stride, cp[stride] = - (unsigned char) ((cp[stride] + cp[0]) & 0xff); cp++) - count -= stride; - } - - _TIFFmemcpy(tmp, cp0, cc); - cp = (uint8_t *) cp0; - for (count = 0; count < wc; count++) { - uint32_t byte; - for (byte = 0; byte < bps; byte++) { - #if WORDS_BIGENDIAN - cp[bps * count + byte] = tmp[byte * wc + count]; - #else - cp[bps * count + byte] = - tmp[(bps - byte - 1) * wc + count]; - #endif - } - } - _TIFFfreeExt(tif, tmp); + if (!tmp) + return 0; + + while (count > stride) + { + REPEAT4(stride, + cp[stride] = (unsigned char)((cp[stride] + cp[0]) & 0xff); + cp++) + count -= stride; + } + + _TIFFmemcpy(tmp, cp0, cc); + cp = (uint8_t *)cp0; + for (count = 0; count < wc; count++) + { + uint32_t byte; + for (byte = 0; byte < bps; byte++) + { +#if WORDS_BIGENDIAN + cp[bps * count + byte] = tmp[byte * wc + count]; +#else + cp[bps * count + byte] = tmp[(bps - byte - 1) * wc + count]; +#endif + } + } + _TIFFfreeExt(tif, tmp); return 1; } /* * Decode a scanline and apply the predictor routine. */ -static int -PredictorDecodeRow(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) +static int PredictorDecodeRow(TIFF *tif, uint8_t *op0, tmsize_t occ0, + uint16_t s) { - TIFFPredictorState *sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != NULL); - assert(sp->decoderow != NULL); - assert(sp->decodepfunc != NULL); + assert(sp != NULL); + assert(sp->decoderow != NULL); + assert(sp->decodepfunc != NULL); - if ((*sp->decoderow)(tif, op0, occ0, s)) { - return (*sp->decodepfunc)(tif, op0, occ0); - } else - return 0; + if ((*sp->decoderow)(tif, op0, occ0, s)) + { + return (*sp->decodepfunc)(tif, op0, occ0); + } + else + return 0; } /* @@ -517,123 +578,152 @@ PredictorDecodeRow(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) * been calculated at pre-decode time according to the * strip/tile dimensions. */ -static int -PredictorDecodeTile(TIFF* tif, uint8_t* op0, tmsize_t occ0, uint16_t s) +static int PredictorDecodeTile(TIFF *tif, uint8_t *op0, tmsize_t occ0, + uint16_t s) { - TIFFPredictorState *sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != NULL); - assert(sp->decodetile != NULL); + assert(sp != NULL); + assert(sp->decodetile != NULL); - if ((*sp->decodetile)(tif, op0, occ0, s)) { - tmsize_t rowsize = sp->rowsize; - assert(rowsize > 0); - if((occ0%rowsize) !=0) + if ((*sp->decodetile)(tif, op0, occ0, s)) + { + tmsize_t rowsize = sp->rowsize; + assert(rowsize > 0); + if ((occ0 % rowsize) != 0) { - TIFFErrorExtR(tif, "PredictorDecodeTile", - "%s", "occ0%rowsize != 0"); + TIFFErrorExtR(tif, "PredictorDecodeTile", "%s", + "occ0%rowsize != 0"); return 0; } - assert(sp->decodepfunc != NULL); - while (occ0 > 0) { - if( !(*sp->decodepfunc)(tif, op0, rowsize) ) + assert(sp->decodepfunc != NULL); + while (occ0 > 0) + { + if (!(*sp->decodepfunc)(tif, op0, rowsize)) return 0; - occ0 -= rowsize; - op0 += rowsize; - } - return 1; - } else - return 0; + occ0 -= rowsize; + op0 += rowsize; + } + return 1; + } + else + return 0; } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horDiff8(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int horDiff8(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - TIFFPredictorState* sp = PredictorState(tif); - tmsize_t stride = sp->stride; - unsigned char* cp = (unsigned char*) cp0; + TIFFPredictorState *sp = PredictorState(tif); + tmsize_t stride = sp->stride; + unsigned char *cp = (unsigned char *)cp0; - if((cc%stride)!=0) + if ((cc % stride) != 0) { - TIFFErrorExtR(tif, "horDiff8", - "%s", "(cc%stride)!=0"); + TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%stride)!=0"); return 0; } - if (cc > stride) { - cc -= stride; - /* - * Pipeline the most common cases. - */ - if (stride == 3) { - unsigned int r1, g1, b1; - unsigned int r2 = cp[0]; - unsigned int g2 = cp[1]; - unsigned int b2 = cp[2]; - do { - r1 = cp[3]; cp[3] = (unsigned char)((r1-r2)&0xff); r2 = r1; - g1 = cp[4]; cp[4] = (unsigned char)((g1-g2)&0xff); g2 = g1; - b1 = cp[5]; cp[5] = (unsigned char)((b1-b2)&0xff); b2 = b1; - cp += 3; - } while ((cc -= 3) > 0); - } else if (stride == 4) { - unsigned int r1, g1, b1, a1; - unsigned int r2 = cp[0]; - unsigned int g2 = cp[1]; - unsigned int b2 = cp[2]; - unsigned int a2 = cp[3]; - do { - r1 = cp[4]; cp[4] = (unsigned char)((r1-r2)&0xff); r2 = r1; - g1 = cp[5]; cp[5] = (unsigned char)((g1-g2)&0xff); g2 = g1; - b1 = cp[6]; cp[6] = (unsigned char)((b1-b2)&0xff); b2 = b1; - a1 = cp[7]; cp[7] = (unsigned char)((a1-a2)&0xff); a2 = a1; - cp += 4; - } while ((cc -= 4) > 0); - } else { - cp += cc - 1; - do { - REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--) - } while ((cc -= stride) > 0); - } - } - return 1; + if (cc > stride) + { + cc -= stride; + /* + * Pipeline the most common cases. + */ + if (stride == 3) + { + unsigned int r1, g1, b1; + unsigned int r2 = cp[0]; + unsigned int g2 = cp[1]; + unsigned int b2 = cp[2]; + do + { + r1 = cp[3]; + cp[3] = (unsigned char)((r1 - r2) & 0xff); + r2 = r1; + g1 = cp[4]; + cp[4] = (unsigned char)((g1 - g2) & 0xff); + g2 = g1; + b1 = cp[5]; + cp[5] = (unsigned char)((b1 - b2) & 0xff); + b2 = b1; + cp += 3; + } while ((cc -= 3) > 0); + } + else if (stride == 4) + { + unsigned int r1, g1, b1, a1; + unsigned int r2 = cp[0]; + unsigned int g2 = cp[1]; + unsigned int b2 = cp[2]; + unsigned int a2 = cp[3]; + do + { + r1 = cp[4]; + cp[4] = (unsigned char)((r1 - r2) & 0xff); + r2 = r1; + g1 = cp[5]; + cp[5] = (unsigned char)((g1 - g2) & 0xff); + g2 = g1; + b1 = cp[6]; + cp[6] = (unsigned char)((b1 - b2) & 0xff); + b2 = b1; + a1 = cp[7]; + cp[7] = (unsigned char)((a1 - a2) & 0xff); + a2 = a1; + cp += 4; + } while ((cc -= 4) > 0); + } + else + { + cp += cc - 1; + do + { + REPEAT4(stride, + cp[stride] = + (unsigned char)((cp[stride] - cp[0]) & 0xff); + cp--) + } while ((cc -= stride) > 0); + } + } + return 1; } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horDiff16(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int horDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - TIFFPredictorState* sp = PredictorState(tif); - tmsize_t stride = sp->stride; - uint16_t *wp = (uint16_t*) cp0; - tmsize_t wc = cc/2; + TIFFPredictorState *sp = PredictorState(tif); + tmsize_t stride = sp->stride; + uint16_t *wp = (uint16_t *)cp0; + tmsize_t wc = cc / 2; - if((cc%(2*stride))!=0) + if ((cc % (2 * stride)) != 0) { - TIFFErrorExtR(tif, "horDiff8", - "%s", "(cc%(2*stride))!=0"); + TIFFErrorExtR(tif, "horDiff8", "%s", "(cc%(2*stride))!=0"); return 0; } - if (wc > stride) { - wc -= stride; - wp += wc - 1; - do { - REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] - (unsigned int)wp[0]) & 0xffff); wp--) - wc -= stride; - } while (wc > 0); - } - return 1; + if (wc > stride) + { + wc -= stride; + wp += wc - 1; + do + { + REPEAT4(stride, wp[stride] = (uint16_t)(((unsigned int)wp[stride] - + (unsigned int)wp[0]) & + 0xffff); + wp--) + wc -= stride; + } while (wc > 0); + } + return 1; } -static int -swabHorDiff16(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int swabHorDiff16(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - uint16_t* wp = (uint16_t*) cp0; + uint16_t *wp = (uint16_t *)cp0; tmsize_t wc = cc / 2; - if( !horDiff16(tif, cp0, cc) ) + if (!horDiff16(tif, cp0, cc)) return 0; TIFFSwabArrayOfShort(wp, wc); @@ -641,39 +731,38 @@ swabHorDiff16(TIFF* tif, uint8_t* cp0, tmsize_t cc) } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int horDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - TIFFPredictorState* sp = PredictorState(tif); - tmsize_t stride = sp->stride; - uint32_t *wp = (uint32_t*) cp0; - tmsize_t wc = cc/4; + TIFFPredictorState *sp = PredictorState(tif); + tmsize_t stride = sp->stride; + uint32_t *wp = (uint32_t *)cp0; + tmsize_t wc = cc / 4; - if((cc%(4*stride))!=0) + if ((cc % (4 * stride)) != 0) { - TIFFErrorExtR(tif, "horDiff32", - "%s", "(cc%(4*stride))!=0"); + TIFFErrorExtR(tif, "horDiff32", "%s", "(cc%(4*stride))!=0"); return 0; } - if (wc > stride) { - wc -= stride; - wp += wc - 1; - do { - REPEAT4(stride, wp[stride] -= wp[0]; wp--) - wc -= stride; - } while (wc > 0); - } - return 1; + if (wc > stride) + { + wc -= stride; + wp += wc - 1; + do + { + REPEAT4(stride, wp[stride] -= wp[0]; wp--) + wc -= stride; + } while (wc > 0); + } + return 1; } -static int -swabHorDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int swabHorDiff32(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - uint32_t* wp = (uint32_t*) cp0; + uint32_t *wp = (uint32_t *)cp0; tmsize_t wc = cc / 4; - if( !horDiff32(tif, cp0, cc) ) + if (!horDiff32(tif, cp0, cc)) return 0; TIFFSwabArrayOfLong(wp, wc); @@ -681,36 +770,35 @@ swabHorDiff32(TIFF* tif, uint8_t* cp0, tmsize_t cc) } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -horDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int horDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - TIFFPredictorState* sp = PredictorState(tif); - tmsize_t stride = sp->stride; - uint64_t *wp = (uint64_t*) cp0; - tmsize_t wc = cc/8; - - if ((cc % (8 * stride)) != 0) - { - TIFFErrorExtR(tif, "horDiff64", - "%s", "(cc%(8*stride))!=0"); - return 0; - } - - if (wc > stride) { - wc -= stride; - wp += wc - 1; - do { - REPEAT4(stride, wp[stride] -= wp[0]; wp--) - wc -= stride; - } while (wc > 0); - } - return 1; + TIFFPredictorState *sp = PredictorState(tif); + tmsize_t stride = sp->stride; + uint64_t *wp = (uint64_t *)cp0; + tmsize_t wc = cc / 8; + + if ((cc % (8 * stride)) != 0) + { + TIFFErrorExtR(tif, "horDiff64", "%s", "(cc%(8*stride))!=0"); + return 0; + } + + if (wc > stride) + { + wc -= stride; + wp += wc - 1; + do + { + REPEAT4(stride, wp[stride] -= wp[0]; wp--) + wc -= stride; + } while (wc > 0); + } + return 1; } -static int -swabHorDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int swabHorDiff64(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - uint64_t* wp = (uint64_t*) cp0; + uint64_t *wp = (uint64_t *)cp0; tmsize_t wc = cc / 8; if (!horDiff64(tif, cp0, cc)) @@ -724,229 +812,235 @@ swabHorDiff64(TIFF* tif, uint8_t* cp0, tmsize_t cc) * Floating point predictor differencing routine. */ TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static int -fpDiff(TIFF* tif, uint8_t* cp0, tmsize_t cc) +static int fpDiff(TIFF *tif, uint8_t *cp0, tmsize_t cc) { - tmsize_t stride = PredictorState(tif)->stride; - uint32_t bps = tif->tif_dir.td_bitspersample / 8; - tmsize_t wc = cc / bps; - tmsize_t count; - uint8_t *cp = (uint8_t *) cp0; - uint8_t *tmp; - - if((cc%(bps*stride))!=0) + tmsize_t stride = PredictorState(tif)->stride; + uint32_t bps = tif->tif_dir.td_bitspersample / 8; + tmsize_t wc = cc / bps; + tmsize_t count; + uint8_t *cp = (uint8_t *)cp0; + uint8_t *tmp; + + if ((cc % (bps * stride)) != 0) { - TIFFErrorExtR(tif, "fpDiff", - "%s", "(cc%(bps*stride))!=0"); + TIFFErrorExtR(tif, "fpDiff", "%s", "(cc%(bps*stride))!=0"); return 0; } tmp = (uint8_t *)_TIFFmallocExt(tif, cc); - if (!tmp) - return 0; - - _TIFFmemcpy(tmp, cp0, cc); - for (count = 0; count < wc; count++) { - uint32_t byte; - for (byte = 0; byte < bps; byte++) { - #if WORDS_BIGENDIAN - cp[byte * wc + count] = tmp[bps * count + byte]; - #else - cp[(bps - byte - 1) * wc + count] = - tmp[bps * count + byte]; - #endif - } - } - _TIFFfreeExt(tif, tmp); - - cp = (uint8_t *) cp0; - cp += cc - stride - 1; - for (count = cc; count > stride; count -= stride) - REPEAT4(stride, cp[stride] = (unsigned char)((cp[stride] - cp[0])&0xff); cp--) + if (!tmp) + return 0; + + _TIFFmemcpy(tmp, cp0, cc); + for (count = 0; count < wc; count++) + { + uint32_t byte; + for (byte = 0; byte < bps; byte++) + { +#if WORDS_BIGENDIAN + cp[byte * wc + count] = tmp[bps * count + byte]; +#else + cp[(bps - byte - 1) * wc + count] = tmp[bps * count + byte]; +#endif + } + } + _TIFFfreeExt(tif, tmp); + + cp = (uint8_t *)cp0; + cp += cc - stride - 1; + for (count = cc; count > stride; count -= stride) + REPEAT4(stride, + cp[stride] = (unsigned char)((cp[stride] - cp[0]) & 0xff); + cp--) return 1; } -static int -PredictorEncodeRow(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int PredictorEncodeRow(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - TIFFPredictorState *sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != NULL); - assert(sp->encodepfunc != NULL); - assert(sp->encoderow != NULL); + assert(sp != NULL); + assert(sp->encodepfunc != NULL); + assert(sp->encoderow != NULL); - /* XXX horizontal differencing alters user's data XXX */ - if( !(*sp->encodepfunc)(tif, bp, cc) ) + /* XXX horizontal differencing alters user's data XXX */ + if (!(*sp->encodepfunc)(tif, bp, cc)) return 0; - return (*sp->encoderow)(tif, bp, cc, s); + return (*sp->encoderow)(tif, bp, cc, s); } -static int -PredictorEncodeTile(TIFF* tif, uint8_t* bp0, tmsize_t cc0, uint16_t s) +static int PredictorEncodeTile(TIFF *tif, uint8_t *bp0, tmsize_t cc0, + uint16_t s) { - static const char module[] = "PredictorEncodeTile"; - TIFFPredictorState *sp = PredictorState(tif); - uint8_t *working_copy; - tmsize_t cc = cc0, rowsize; - unsigned char* bp; - int result_code; - - assert(sp != NULL); - assert(sp->encodepfunc != NULL); - assert(sp->encodetile != NULL); - - /* - * Do predictor manipulation in a working buffer to avoid altering - * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965 - */ - working_copy = (uint8_t*) _TIFFmallocExt(tif, cc0); - if( working_copy == NULL ) - { - TIFFErrorExtR(tif, module, - "Out of memory allocating %" PRId64 " byte temp buffer.", - (int64_t) cc0 ); - return 0; - } - memcpy( working_copy, bp0, cc0 ); - bp = working_copy; + static const char module[] = "PredictorEncodeTile"; + TIFFPredictorState *sp = PredictorState(tif); + uint8_t *working_copy; + tmsize_t cc = cc0, rowsize; + unsigned char *bp; + int result_code; + + assert(sp != NULL); + assert(sp->encodepfunc != NULL); + assert(sp->encodetile != NULL); + + /* + * Do predictor manipulation in a working buffer to avoid altering + * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965 + */ + working_copy = (uint8_t *)_TIFFmallocExt(tif, cc0); + if (working_copy == NULL) + { + TIFFErrorExtR(tif, module, + "Out of memory allocating %" PRId64 " byte temp buffer.", + (int64_t)cc0); + return 0; + } + memcpy(working_copy, bp0, cc0); + bp = working_copy; - rowsize = sp->rowsize; - assert(rowsize > 0); - if((cc0%rowsize)!=0) + rowsize = sp->rowsize; + assert(rowsize > 0); + if ((cc0 % rowsize) != 0) { - TIFFErrorExtR(tif, "PredictorEncodeTile", - "%s", "(cc0%rowsize)!=0"); - _TIFFfreeExt(tif, working_copy ); + TIFFErrorExtR(tif, "PredictorEncodeTile", "%s", "(cc0%rowsize)!=0"); + _TIFFfreeExt(tif, working_copy); return 0; } - while (cc > 0) { - (*sp->encodepfunc)(tif, bp, rowsize); - cc -= rowsize; - bp += rowsize; - } - result_code = (*sp->encodetile)(tif, working_copy, cc0, s); + while (cc > 0) + { + (*sp->encodepfunc)(tif, bp, rowsize); + cc -= rowsize; + bp += rowsize; + } + result_code = (*sp->encodetile)(tif, working_copy, cc0, s); - _TIFFfreeExt(tif, working_copy ); + _TIFFfreeExt(tif, working_copy); - return result_code; + return result_code; } -#define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */ +#define FIELD_PREDICTOR (FIELD_CODEC + 0) /* XXX */ static const TIFFField predictFields[] = { - { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL }, + {TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, + TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL}, }; -static int -PredictorVSetField(TIFF* tif, uint32_t tag, va_list ap) +static int PredictorVSetField(TIFF *tif, uint32_t tag, va_list ap) { - TIFFPredictorState *sp = PredictorState(tif); - - assert(sp != NULL); - assert(sp->vsetparent != NULL); - - switch (tag) { - case TIFFTAG_PREDICTOR: - sp->predictor = (uint16_t) va_arg(ap, uint16_vap); - TIFFSetFieldBit(tif, FIELD_PREDICTOR); - break; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - tif->tif_flags |= TIFF_DIRTYDIRECT; - return 1; + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != NULL); + assert(sp->vsetparent != NULL); + + switch (tag) + { + case TIFFTAG_PREDICTOR: + sp->predictor = (uint16_t)va_arg(ap, uint16_vap); + TIFFSetFieldBit(tif, FIELD_PREDICTOR); + break; + default: + return (*sp->vsetparent)(tif, tag, ap); + } + tif->tif_flags |= TIFF_DIRTYDIRECT; + return 1; } -static int -PredictorVGetField(TIFF* tif, uint32_t tag, va_list ap) +static int PredictorVGetField(TIFF *tif, uint32_t tag, va_list ap) { - TIFFPredictorState *sp = PredictorState(tif); - - assert(sp != NULL); - assert(sp->vgetparent != NULL); - - switch (tag) { - case TIFFTAG_PREDICTOR: - *va_arg(ap, uint16_t*) = (uint16_t)sp->predictor; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != NULL); + assert(sp->vgetparent != NULL); + + switch (tag) + { + case TIFFTAG_PREDICTOR: + *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; } -static void -PredictorPrintDir(TIFF* tif, FILE* fd, long flags) +static void PredictorPrintDir(TIFF *tif, FILE *fd, long flags) { - TIFFPredictorState* sp = PredictorState(tif); - - (void) flags; - if (TIFFFieldSet(tif,FIELD_PREDICTOR)) { - fprintf(fd, " Predictor: "); - switch (sp->predictor) { - case 1: fprintf(fd, "none "); break; - case 2: fprintf(fd, "horizontal differencing "); break; - case 3: fprintf(fd, "floating point predictor "); break; - } - fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor); - } - if (sp->printdir) - (*sp->printdir)(tif, fd, flags); + TIFFPredictorState *sp = PredictorState(tif); + + (void)flags; + if (TIFFFieldSet(tif, FIELD_PREDICTOR)) + { + fprintf(fd, " Predictor: "); + switch (sp->predictor) + { + case 1: + fprintf(fd, "none "); + break; + case 2: + fprintf(fd, "horizontal differencing "); + break; + case 3: + fprintf(fd, "floating point predictor "); + break; + } + fprintf(fd, "%d (0x%x)\n", sp->predictor, sp->predictor); + } + if (sp->printdir) + (*sp->printdir)(tif, fd, flags); } -int -TIFFPredictorInit(TIFF* tif) +int TIFFPredictorInit(TIFF *tif) { - TIFFPredictorState* sp = PredictorState(tif); - - assert(sp != 0); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, predictFields, - TIFFArrayCount(predictFields))) { - TIFFErrorExtR(tif, "TIFFPredictorInit", - "Merging Predictor codec-specific tags failed"); - return 0; - } - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = - PredictorVGetField;/* hook for predictor tag */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = - PredictorVSetField;/* hook for predictor tag */ - sp->printdir = tif->tif_tagmethods.printdir; - tif->tif_tagmethods.printdir = - PredictorPrintDir; /* hook for predictor tag */ - - sp->setupdecode = tif->tif_setupdecode; - tif->tif_setupdecode = PredictorSetupDecode; - sp->setupencode = tif->tif_setupencode; - tif->tif_setupencode = PredictorSetupEncode; - - sp->predictor = 1; /* default value */ - sp->encodepfunc = NULL; /* no predictor routine */ - sp->decodepfunc = NULL; /* no predictor routine */ - return 1; + TIFFPredictorState *sp = PredictorState(tif); + + assert(sp != 0); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, predictFields, TIFFArrayCount(predictFields))) + { + TIFFErrorExtR(tif, "TIFFPredictorInit", + "Merging Predictor codec-specific tags failed"); + return 0; + } + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = + PredictorVGetField; /* hook for predictor tag */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = + PredictorVSetField; /* hook for predictor tag */ + sp->printdir = tif->tif_tagmethods.printdir; + tif->tif_tagmethods.printdir = + PredictorPrintDir; /* hook for predictor tag */ + + sp->setupdecode = tif->tif_setupdecode; + tif->tif_setupdecode = PredictorSetupDecode; + sp->setupencode = tif->tif_setupencode; + tif->tif_setupencode = PredictorSetupEncode; + + sp->predictor = 1; /* default value */ + sp->encodepfunc = NULL; /* no predictor routine */ + sp->decodepfunc = NULL; /* no predictor routine */ + return 1; } -int -TIFFPredictorCleanup(TIFF* tif) +int TIFFPredictorCleanup(TIFF *tif) { - TIFFPredictorState* sp = PredictorState(tif); + TIFFPredictorState *sp = PredictorState(tif); - assert(sp != 0); + assert(sp != 0); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; - tif->tif_tagmethods.printdir = sp->printdir; - tif->tif_setupdecode = sp->setupdecode; - tif->tif_setupencode = sp->setupencode; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.printdir = sp->printdir; + tif->tif_setupdecode = sp->setupdecode; + tif->tif_setupencode = sp->setupencode; - return 1; + return 1; } diff --git a/libtiff/tif_predict.h b/libtiff/tif_predict.h index 29d16753..de773283 100644 --- a/libtiff/tif_predict.h +++ b/libtiff/tif_predict.h @@ -23,7 +23,7 @@ */ #ifndef _TIFFPREDICT_ -#define _TIFFPREDICT_ +#define _TIFFPREDICT_ #include "tiffio.h" #include "tiffiop.h" @@ -32,40 +32,42 @@ * ``Library-private'' Support for the Predictor Tag */ -typedef int (*TIFFEncodeDecodeMethod)(TIFF* tif, uint8_t* buf, tmsize_t size); +typedef int (*TIFFEncodeDecodeMethod)(TIFF *tif, uint8_t *buf, tmsize_t size); /* * Codecs that want to support the Predictor tag must place * this structure first in their private state block so that * the predictor code can cast tif_data to find its state. */ -typedef struct { - int predictor; /* predictor tag value */ - tmsize_t stride; /* sample stride over data */ - tmsize_t rowsize; /* tile/strip row size */ +typedef struct +{ + int predictor; /* predictor tag value */ + tmsize_t stride; /* sample stride over data */ + tmsize_t rowsize; /* tile/strip row size */ - TIFFCodeMethod encoderow; /* parent codec encode/decode row */ - TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */ - TIFFCodeMethod encodetile; /* parent codec encode/decode tile */ - TIFFEncodeDecodeMethod encodepfunc; /* horizontal differencer */ + TIFFCodeMethod encoderow; /* parent codec encode/decode row */ + TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */ + TIFFCodeMethod encodetile; /* parent codec encode/decode tile */ + TIFFEncodeDecodeMethod encodepfunc; /* horizontal differencer */ - TIFFCodeMethod decoderow; /* parent codec encode/decode row */ - TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */ - TIFFCodeMethod decodetile; /* parent codec encode/decode tile */ - TIFFEncodeDecodeMethod decodepfunc; /* horizontal accumulator */ + TIFFCodeMethod decoderow; /* parent codec encode/decode row */ + TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */ + TIFFCodeMethod decodetile; /* parent codec encode/decode tile */ + TIFFEncodeDecodeMethod decodepfunc; /* horizontal accumulator */ - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ - TIFFPrintMethod printdir; /* super-class method */ - TIFFBoolMethod setupdecode; /* super-class method */ - TIFFBoolMethod setupencode; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ + TIFFPrintMethod printdir; /* super-class method */ + TIFFBoolMethod setupdecode; /* super-class method */ + TIFFBoolMethod setupencode; /* super-class method */ } TIFFPredictorState; #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -extern int TIFFPredictorInit(TIFF*); -extern int TIFFPredictorCleanup(TIFF*); + extern int TIFFPredictorInit(TIFF *); + extern int TIFFPredictorCleanup(TIFF *); #if defined(__cplusplus) } #endif diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c index 868121f2..2b7fd176 100644 --- a/libtiff/tif_print.c +++ b/libtiff/tif_print.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -32,667 +32,724 @@ #include <ctype.h> -static void -_TIFFprintAsciiBounded(FILE* fd, const char* cp, size_t max_chars); - -static const char * const photoNames[] = { - "min-is-white", /* PHOTOMETRIC_MINISWHITE */ - "min-is-black", /* PHOTOMETRIC_MINISBLACK */ - "RGB color", /* PHOTOMETRIC_RGB */ - "palette color (RGB from colormap)", /* PHOTOMETRIC_PALETTE */ - "transparency mask", /* PHOTOMETRIC_MASK */ - "separated", /* PHOTOMETRIC_SEPARATED */ - "YCbCr", /* PHOTOMETRIC_YCBCR */ +static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars); + +static const char *const photoNames[] = { + "min-is-white", /* PHOTOMETRIC_MINISWHITE */ + "min-is-black", /* PHOTOMETRIC_MINISBLACK */ + "RGB color", /* PHOTOMETRIC_RGB */ + "palette color (RGB from colormap)", /* PHOTOMETRIC_PALETTE */ + "transparency mask", /* PHOTOMETRIC_MASK */ + "separated", /* PHOTOMETRIC_SEPARATED */ + "YCbCr", /* PHOTOMETRIC_YCBCR */ "7 (0x7)", - "CIE L*a*b*", /* PHOTOMETRIC_CIELAB */ - "ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */ - "ITU L*a*b*" /* PHOTOMETRIC_ITULAB */ + "CIE L*a*b*", /* PHOTOMETRIC_CIELAB */ + "ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */ + "ITU L*a*b*" /* PHOTOMETRIC_ITULAB */ }; -#define NPHOTONAMES (sizeof (photoNames) / sizeof (photoNames[0])) +#define NPHOTONAMES (sizeof(photoNames) / sizeof(photoNames[0])) -static const char * const orientNames[] = { +static const char *const orientNames[] = { "0 (0x0)", - "row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */ - "row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */ - "row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */ - "row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */ - "row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */ - "row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */ - "row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */ - "row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */ + "row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */ + "row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */ + "row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */ + "row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */ + "row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */ + "row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */ + "row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */ + "row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */ }; -#define NORIENTNAMES (sizeof (orientNames) / sizeof (orientNames[0])) +#define NORIENTNAMES (sizeof(orientNames) / sizeof(orientNames[0])) -static const struct tagname { +static const struct tagname +{ uint16_t tag; - const char* name; + const char *name; } tagnames[] = { - { TIFFTAG_GDAL_METADATA, "GDAL Metadata" }, - { TIFFTAG_GDAL_NODATA, "GDAL NoDataValue" }, + {TIFFTAG_GDAL_METADATA, "GDAL Metadata"}, + {TIFFTAG_GDAL_NODATA, "GDAL NoDataValue"}, }; -#define NTAGS (sizeof (tagnames) / sizeof (tagnames[0])) +#define NTAGS (sizeof(tagnames) / sizeof(tagnames[0])) -static void -_TIFFPrintField(FILE* fd, const TIFFField *fip, - uint32_t value_count, void *raw_data) +static void _TIFFPrintField(FILE *fd, const TIFFField *fip, + uint32_t value_count, void *raw_data) { - uint32_t j; + uint32_t j; /* Print a user-friendly name for tags of relatively common use, but */ /* which aren't registered by libtiff itself. */ - const char* field_name = fip->field_name; - if( TIFFFieldIsAnonymous(fip) ) { - for( size_t i = 0; i < NTAGS; ++i ) { - if( fip->field_tag == tagnames[i].tag ) { + const char *field_name = fip->field_name; + if (TIFFFieldIsAnonymous(fip)) + { + for (size_t i = 0; i < NTAGS; ++i) + { + if (fip->field_tag == tagnames[i].tag) + { field_name = tagnames[i].name; break; } } } - fprintf(fd, " %s: ", field_name); - - for(j = 0; j < value_count; j++) { - if(fip->field_type == TIFF_BYTE) - fprintf(fd, "%"PRIu8, ((uint8_t *) raw_data)[j]); - else if(fip->field_type == TIFF_UNDEFINED) - fprintf(fd, "0x%"PRIx8, ((uint8_t *) raw_data)[j]); - else if(fip->field_type == TIFF_SBYTE) - fprintf(fd, "%"PRId8, ((int8_t *) raw_data)[j]); - else if(fip->field_type == TIFF_SHORT) - fprintf(fd, "%"PRIu16, ((uint16_t *) raw_data)[j]); - else if(fip->field_type == TIFF_SSHORT) - fprintf(fd, "%"PRId16, ((int16_t *) raw_data)[j]); - else if(fip->field_type == TIFF_LONG) - fprintf(fd, "%"PRIu32, ((uint32_t *) raw_data)[j]); - else if(fip->field_type == TIFF_SLONG) - fprintf(fd, "%"PRId32, ((int32_t *) raw_data)[j]); - else if(fip->field_type == TIFF_IFD) - fprintf(fd, "0x%"PRIx32, ((uint32_t *) raw_data)[j]); - else if (fip->field_type == TIFF_RATIONAL - || fip->field_type == TIFF_SRATIONAL) { - int tv_size = TIFFFieldSetGetSize(fip); - if(tv_size==8) - fprintf(fd, "%lf", ((double*)raw_data)[j]); - else - fprintf(fd, "%f", ((float *) raw_data)[j]); - } - else if(fip->field_type == TIFF_FLOAT) - fprintf(fd, "%f", ((float*)raw_data)[j]); - else if(fip->field_type == TIFF_LONG8) - fprintf(fd, "%"PRIu64, ((uint64_t *) raw_data)[j]); - else if(fip->field_type == TIFF_SLONG8) - fprintf(fd, "%"PRId64, ((int64_t *) raw_data)[j]); - else if(fip->field_type == TIFF_IFD8) - fprintf(fd, "0x%"PRIx64, ((uint64_t *) raw_data)[j]); - else if(fip->field_type == TIFF_DOUBLE) - fprintf(fd, "%lf", ((double *) raw_data)[j]); - else if(fip->field_type == TIFF_ASCII) { - fprintf(fd, "%s", (char *) raw_data); - break; - } - else { - fprintf(fd, "<unsupported data type in TIFFPrint>"); - break; - } - - if(j < value_count - 1) - fprintf(fd, ","); - } - - fprintf(fd, "\n"); + fprintf(fd, " %s: ", field_name); + + for (j = 0; j < value_count; j++) + { + if (fip->field_type == TIFF_BYTE) + fprintf(fd, "%" PRIu8, ((uint8_t *)raw_data)[j]); + else if (fip->field_type == TIFF_UNDEFINED) + fprintf(fd, "0x%" PRIx8, ((uint8_t *)raw_data)[j]); + else if (fip->field_type == TIFF_SBYTE) + fprintf(fd, "%" PRId8, ((int8_t *)raw_data)[j]); + else if (fip->field_type == TIFF_SHORT) + fprintf(fd, "%" PRIu16, ((uint16_t *)raw_data)[j]); + else if (fip->field_type == TIFF_SSHORT) + fprintf(fd, "%" PRId16, ((int16_t *)raw_data)[j]); + else if (fip->field_type == TIFF_LONG) + fprintf(fd, "%" PRIu32, ((uint32_t *)raw_data)[j]); + else if (fip->field_type == TIFF_SLONG) + fprintf(fd, "%" PRId32, ((int32_t *)raw_data)[j]); + else if (fip->field_type == TIFF_IFD) + fprintf(fd, "0x%" PRIx32, ((uint32_t *)raw_data)[j]); + else if (fip->field_type == TIFF_RATIONAL || + fip->field_type == TIFF_SRATIONAL) + { + int tv_size = TIFFFieldSetGetSize(fip); + if (tv_size == 8) + fprintf(fd, "%lf", ((double *)raw_data)[j]); + else + fprintf(fd, "%f", ((float *)raw_data)[j]); + } + else if (fip->field_type == TIFF_FLOAT) + fprintf(fd, "%f", ((float *)raw_data)[j]); + else if (fip->field_type == TIFF_LONG8) + fprintf(fd, "%" PRIu64, ((uint64_t *)raw_data)[j]); + else if (fip->field_type == TIFF_SLONG8) + fprintf(fd, "%" PRId64, ((int64_t *)raw_data)[j]); + else if (fip->field_type == TIFF_IFD8) + fprintf(fd, "0x%" PRIx64, ((uint64_t *)raw_data)[j]); + else if (fip->field_type == TIFF_DOUBLE) + fprintf(fd, "%lf", ((double *)raw_data)[j]); + else if (fip->field_type == TIFF_ASCII) + { + fprintf(fd, "%s", (char *)raw_data); + break; + } + else + { + fprintf(fd, "<unsupported data type in TIFFPrint>"); + break; + } + + if (j < value_count - 1) + fprintf(fd, ","); + } + + fprintf(fd, "\n"); } -static int -_TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32_t tag, - uint32_t value_count, void *raw_data) +static int _TIFFPrettyPrintField(TIFF *tif, const TIFFField *fip, FILE *fd, + uint32_t tag, uint32_t value_count, + void *raw_data) { - (void) tif; - - /* do not try to pretty print auto-defined fields */ - if ( TIFFFieldIsAnonymous(fip) ) { - return 0; - } - - switch (tag) - { - case TIFFTAG_INKSET: - if (value_count == 2 && fip->field_type == TIFF_SHORT) { - fprintf(fd, " Ink Set: "); - switch (*((uint16_t*)raw_data)) { - case INKSET_CMYK: - fprintf(fd, "CMYK\n"); - break; - default: - fprintf(fd, "%"PRIu16" (0x%"PRIx16")\n", - *((uint16_t*)raw_data), - *((uint16_t*)raw_data)); - break; - } - return 1; - } - return 0; - - case TIFFTAG_DOTRANGE: - if (value_count == 2 && fip->field_type == TIFF_SHORT) { - fprintf(fd, " Dot Range: %"PRIu16"-%"PRIu16"\n", - ((uint16_t*)raw_data)[0], ((uint16_t*)raw_data)[1]); - return 1; - } - return 0; - - case TIFFTAG_WHITEPOINT: - if (value_count == 2 && fip->field_type == TIFF_RATIONAL) { - fprintf(fd, " White Point: %g-%g\n", - ((float *)raw_data)[0], ((float *)raw_data)[1]); - return 1; - } - return 0; - - case TIFFTAG_XMLPACKET: - { - uint32_t i; - - fprintf(fd, " XMLPacket (XMP Metadata):\n" ); - for(i = 0; i < value_count; i++) - fputc(((char *)raw_data)[i], fd); - fprintf( fd, "\n" ); - return 1; - } - case TIFFTAG_RICHTIFFIPTC: - fprintf(fd, - " RichTIFFIPTC Data: <present>, %"PRIu32" bytes\n", - value_count); - return 1; - - case TIFFTAG_PHOTOSHOP: - fprintf(fd, " Photoshop Data: <present>, %"PRIu32" bytes\n", - value_count); - return 1; - - case TIFFTAG_ICCPROFILE: - fprintf(fd, " ICC Profile: <present>, %"PRIu32" bytes\n", - value_count); - return 1; - - case TIFFTAG_STONITS: - if (value_count == 1 && fip->field_type == TIFF_DOUBLE) { - fprintf(fd, - " Sample to Nits conversion factor: %.4e\n", - *((double*)raw_data)); - return 1; - } - return 0; - } - - return 0; + (void)tif; + + /* do not try to pretty print auto-defined fields */ + if (TIFFFieldIsAnonymous(fip)) + { + return 0; + } + + switch (tag) + { + case TIFFTAG_INKSET: + if (value_count == 2 && fip->field_type == TIFF_SHORT) + { + fprintf(fd, " Ink Set: "); + switch (*((uint16_t *)raw_data)) + { + case INKSET_CMYK: + fprintf(fd, "CMYK\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + *((uint16_t *)raw_data), + *((uint16_t *)raw_data)); + break; + } + return 1; + } + return 0; + + case TIFFTAG_DOTRANGE: + if (value_count == 2 && fip->field_type == TIFF_SHORT) + { + fprintf(fd, " Dot Range: %" PRIu16 "-%" PRIu16 "\n", + ((uint16_t *)raw_data)[0], ((uint16_t *)raw_data)[1]); + return 1; + } + return 0; + + case TIFFTAG_WHITEPOINT: + if (value_count == 2 && fip->field_type == TIFF_RATIONAL) + { + fprintf(fd, " White Point: %g-%g\n", ((float *)raw_data)[0], + ((float *)raw_data)[1]); + return 1; + } + return 0; + + case TIFFTAG_XMLPACKET: + { + uint32_t i; + + fprintf(fd, " XMLPacket (XMP Metadata):\n"); + for (i = 0; i < value_count; i++) + fputc(((char *)raw_data)[i], fd); + fprintf(fd, "\n"); + return 1; + } + case TIFFTAG_RICHTIFFIPTC: + fprintf(fd, " RichTIFFIPTC Data: <present>, %" PRIu32 " bytes\n", + value_count); + return 1; + + case TIFFTAG_PHOTOSHOP: + fprintf(fd, " Photoshop Data: <present>, %" PRIu32 " bytes\n", + value_count); + return 1; + + case TIFFTAG_ICCPROFILE: + fprintf(fd, " ICC Profile: <present>, %" PRIu32 " bytes\n", + value_count); + return 1; + + case TIFFTAG_STONITS: + if (value_count == 1 && fip->field_type == TIFF_DOUBLE) + { + fprintf(fd, " Sample to Nits conversion factor: %.4e\n", + *((double *)raw_data)); + return 1; + } + return 0; + } + + return 0; } /* * Print the contents of the current directory * to the specified stdio file stream. */ -void -TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags) +void TIFFPrintDirectory(TIFF *tif, FILE *fd, long flags) { - TIFFDirectory *td = &tif->tif_dir; - char *sep; - long l, n; - - fprintf(fd, "TIFF Directory at offset 0x%"PRIx64" (%"PRIu64")\n", - tif->tif_diroff, - tif->tif_diroff); - if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) { - fprintf(fd, " Subfile Type:"); - sep = " "; - if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) { - fprintf(fd, "%sreduced-resolution image", sep); - sep = "/"; - } - if (td->td_subfiletype & FILETYPE_PAGE) { - fprintf(fd, "%smulti-page document", sep); - sep = "/"; - } - if (td->td_subfiletype & FILETYPE_MASK) - fprintf(fd, "%stransparency mask", sep); - fprintf(fd, " (%"PRIu32" = 0x%"PRIx32")\n", - td->td_subfiletype, td->td_subfiletype); - } - if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) { - fprintf(fd, " Image Width: %"PRIu32" Image Length: %"PRIu32, - td->td_imagewidth, td->td_imagelength); - if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH)) - fprintf(fd, " Image Depth: %"PRIu32, - td->td_imagedepth); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) { - fprintf(fd, " Tile Width: %"PRIu32" Tile Length: %"PRIu32, - td->td_tilewidth, td->td_tilelength); - if (TIFFFieldSet(tif,FIELD_TILEDEPTH)) - fprintf(fd, " Tile Depth: %"PRIu32, - td->td_tiledepth); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif,FIELD_RESOLUTION)) { - fprintf(fd, " Resolution: %g, %g", - td->td_xresolution, td->td_yresolution); - if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) { - switch (td->td_resolutionunit) { - case RESUNIT_NONE: - fprintf(fd, " (unitless)"); - break; - case RESUNIT_INCH: - fprintf(fd, " pixels/inch"); - break; - case RESUNIT_CENTIMETER: - fprintf(fd, " pixels/cm"); - break; - default: - fprintf(fd, " (unit %"PRIu16" = 0x%"PRIx16")", - td->td_resolutionunit, - td->td_resolutionunit); - break; - } - } - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif,FIELD_POSITION)) - fprintf(fd, " Position: %g, %g\n", - td->td_xposition, td->td_yposition); - if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE)) - fprintf(fd, " Bits/Sample: %"PRIu16"\n", td->td_bitspersample); - if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) { - fprintf(fd, " Sample Format: "); - switch (td->td_sampleformat) { - case SAMPLEFORMAT_VOID: - fprintf(fd, "void\n"); - break; - case SAMPLEFORMAT_INT: - fprintf(fd, "signed integer\n"); - break; - case SAMPLEFORMAT_UINT: - fprintf(fd, "unsigned integer\n"); - break; - case SAMPLEFORMAT_IEEEFP: - fprintf(fd, "IEEE floating point\n"); - break; - case SAMPLEFORMAT_COMPLEXINT: - fprintf(fd, "complex signed integer\n"); - break; - case SAMPLEFORMAT_COMPLEXIEEEFP: - fprintf(fd, "complex IEEE floating point\n"); - break; - default: - fprintf(fd, "%"PRIu16" (0x%"PRIx16")\n", - td->td_sampleformat, td->td_sampleformat); - break; - } - } - if (TIFFFieldSet(tif,FIELD_COMPRESSION)) { - const TIFFCodec* c = TIFFFindCODEC(td->td_compression); - fprintf(fd, " Compression Scheme: "); - if (c) - fprintf(fd, "%s\n", c->name); - else - fprintf(fd, "%"PRIu16" (0x%"PRIx16")\n", - td->td_compression, td->td_compression); - } - if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) { - fprintf(fd, " Photometric Interpretation: "); - if (td->td_photometric < NPHOTONAMES) - fprintf(fd, "%s\n", photoNames[td->td_photometric]); - else { - switch (td->td_photometric) { - case PHOTOMETRIC_LOGL: - fprintf(fd, "CIE Log2(L)\n"); - break; - case PHOTOMETRIC_LOGLUV: - fprintf(fd, "CIE Log2(L) (u',v')\n"); - break; - default: - fprintf(fd, "%"PRIu16" (0x%"PRIx16")\n", - td->td_photometric, td->td_photometric); - break; - } - } - } - if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) { - uint16_t i; - fprintf(fd, " Extra Samples: %"PRIu16"<", td->td_extrasamples); - sep = ""; - for (i = 0; i < td->td_extrasamples; i++) { - switch (td->td_sampleinfo[i]) { - case EXTRASAMPLE_UNSPECIFIED: - fprintf(fd, "%sunspecified", sep); - break; - case EXTRASAMPLE_ASSOCALPHA: - fprintf(fd, "%sassoc-alpha", sep); - break; - case EXTRASAMPLE_UNASSALPHA: - fprintf(fd, "%sunassoc-alpha", sep); - break; - default: - fprintf(fd, "%s%"PRIu16" (0x%"PRIx16")", sep, - td->td_sampleinfo[i], td->td_sampleinfo[i]); - break; - } - sep = ", "; - } - fprintf(fd, ">\n"); - } - if (TIFFFieldSet(tif,FIELD_INKNAMES)) { - char* cp; - uint16_t i; - fprintf(fd, " Ink Names: "); - i = td->td_samplesperpixel; - sep = ""; - for (cp = td->td_inknames; - i > 0 && cp < td->td_inknames + td->td_inknameslen; - cp = strchr(cp,'\0')+1, i--) { - size_t max_chars = - td->td_inknameslen - (cp - td->td_inknames); - fputs(sep, fd); - _TIFFprintAsciiBounded(fd, cp, max_chars); - sep = ", "; - } - fputs("\n", fd); - } - if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) { - fprintf(fd, " NumberOfInks: %d\n", - td->td_numberofinks); - } - if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) { - fprintf(fd, " Thresholding: "); - switch (td->td_threshholding) { - case THRESHHOLD_BILEVEL: - fprintf(fd, "bilevel art scan\n"); - break; - case THRESHHOLD_HALFTONE: - fprintf(fd, "halftone or dithered scan\n"); - break; - case THRESHHOLD_ERRORDIFFUSE: - fprintf(fd, "error diffused\n"); - break; - default: - fprintf(fd, "%"PRIu16" (0x%"PRIx16")\n", - td->td_threshholding, td->td_threshholding); - break; - } - } - if (TIFFFieldSet(tif,FIELD_FILLORDER)) { - fprintf(fd, " FillOrder: "); - switch (td->td_fillorder) { - case FILLORDER_MSB2LSB: - fprintf(fd, "msb-to-lsb\n"); - break; - case FILLORDER_LSB2MSB: - fprintf(fd, "lsb-to-msb\n"); - break; - default: - fprintf(fd, "%"PRIu16" (0x%"PRIx16")\n", - td->td_fillorder, td->td_fillorder); - break; - } - } - if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING)) + TIFFDirectory *td = &tif->tif_dir; + char *sep; + long l, n; + + fprintf(fd, "TIFF Directory at offset 0x%" PRIx64 " (%" PRIu64 ")\n", + tif->tif_diroff, tif->tif_diroff); + if (TIFFFieldSet(tif, FIELD_SUBFILETYPE)) + { + fprintf(fd, " Subfile Type:"); + sep = " "; + if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) + { + fprintf(fd, "%sreduced-resolution image", sep); + sep = "/"; + } + if (td->td_subfiletype & FILETYPE_PAGE) + { + fprintf(fd, "%smulti-page document", sep); + sep = "/"; + } + if (td->td_subfiletype & FILETYPE_MASK) + fprintf(fd, "%stransparency mask", sep); + fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", td->td_subfiletype, + td->td_subfiletype); + } + if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) + { + fprintf(fd, " Image Width: %" PRIu32 " Image Length: %" PRIu32, + td->td_imagewidth, td->td_imagelength); + if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH)) + fprintf(fd, " Image Depth: %" PRIu32, td->td_imagedepth); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) + { + fprintf(fd, " Tile Width: %" PRIu32 " Tile Length: %" PRIu32, + td->td_tilewidth, td->td_tilelength); + if (TIFFFieldSet(tif, FIELD_TILEDEPTH)) + fprintf(fd, " Tile Depth: %" PRIu32, td->td_tiledepth); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_RESOLUTION)) + { + fprintf(fd, " Resolution: %g, %g", td->td_xresolution, + td->td_yresolution); + if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT)) + { + switch (td->td_resolutionunit) + { + case RESUNIT_NONE: + fprintf(fd, " (unitless)"); + break; + case RESUNIT_INCH: + fprintf(fd, " pixels/inch"); + break; + case RESUNIT_CENTIMETER: + fprintf(fd, " pixels/cm"); + break; + default: + fprintf(fd, " (unit %" PRIu16 " = 0x%" PRIx16 ")", + td->td_resolutionunit, td->td_resolutionunit); + break; + } + } + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_POSITION)) + fprintf(fd, " Position: %g, %g\n", td->td_xposition, td->td_yposition); + if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE)) + fprintf(fd, " Bits/Sample: %" PRIu16 "\n", td->td_bitspersample); + if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT)) + { + fprintf(fd, " Sample Format: "); + switch (td->td_sampleformat) + { + case SAMPLEFORMAT_VOID: + fprintf(fd, "void\n"); + break; + case SAMPLEFORMAT_INT: + fprintf(fd, "signed integer\n"); + break; + case SAMPLEFORMAT_UINT: + fprintf(fd, "unsigned integer\n"); + break; + case SAMPLEFORMAT_IEEEFP: + fprintf(fd, "IEEE floating point\n"); + break; + case SAMPLEFORMAT_COMPLEXINT: + fprintf(fd, "complex signed integer\n"); + break; + case SAMPLEFORMAT_COMPLEXIEEEFP: + fprintf(fd, "complex IEEE floating point\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + td->td_sampleformat, td->td_sampleformat); + break; + } + } + if (TIFFFieldSet(tif, FIELD_COMPRESSION)) + { + const TIFFCodec *c = TIFFFindCODEC(td->td_compression); + fprintf(fd, " Compression Scheme: "); + if (c) + fprintf(fd, "%s\n", c->name); + else + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_compression, + td->td_compression); + } + if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC)) + { + fprintf(fd, " Photometric Interpretation: "); + if (td->td_photometric < NPHOTONAMES) + fprintf(fd, "%s\n", photoNames[td->td_photometric]); + else + { + switch (td->td_photometric) + { + case PHOTOMETRIC_LOGL: + fprintf(fd, "CIE Log2(L)\n"); + break; + case PHOTOMETRIC_LOGLUV: + fprintf(fd, "CIE Log2(L) (u',v')\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + td->td_photometric, td->td_photometric); + break; + } + } + } + if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES) && td->td_extrasamples) + { + uint16_t i; + fprintf(fd, " Extra Samples: %" PRIu16 "<", td->td_extrasamples); + sep = ""; + for (i = 0; i < td->td_extrasamples; i++) + { + switch (td->td_sampleinfo[i]) + { + case EXTRASAMPLE_UNSPECIFIED: + fprintf(fd, "%sunspecified", sep); + break; + case EXTRASAMPLE_ASSOCALPHA: + fprintf(fd, "%sassoc-alpha", sep); + break; + case EXTRASAMPLE_UNASSALPHA: + fprintf(fd, "%sunassoc-alpha", sep); + break; + default: + fprintf(fd, "%s%" PRIu16 " (0x%" PRIx16 ")", sep, + td->td_sampleinfo[i], td->td_sampleinfo[i]); + break; + } + sep = ", "; + } + fprintf(fd, ">\n"); + } + if (TIFFFieldSet(tif, FIELD_INKNAMES)) + { + char *cp; + uint16_t i; + fprintf(fd, " Ink Names: "); + i = td->td_samplesperpixel; + sep = ""; + for (cp = td->td_inknames; + i > 0 && cp < td->td_inknames + td->td_inknameslen; + cp = strchr(cp, '\0') + 1, i--) + { + size_t max_chars = td->td_inknameslen - (cp - td->td_inknames); + fputs(sep, fd); + _TIFFprintAsciiBounded(fd, cp, max_chars); + sep = ", "; + } + fputs("\n", fd); + } + if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) + { + fprintf(fd, " NumberOfInks: %d\n", td->td_numberofinks); + } + if (TIFFFieldSet(tif, FIELD_THRESHHOLDING)) + { + fprintf(fd, " Thresholding: "); + switch (td->td_threshholding) + { + case THRESHHOLD_BILEVEL: + fprintf(fd, "bilevel art scan\n"); + break; + case THRESHHOLD_HALFTONE: + fprintf(fd, "halftone or dithered scan\n"); + break; + case THRESHHOLD_ERRORDIFFUSE: + fprintf(fd, "error diffused\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + td->td_threshholding, td->td_threshholding); + break; + } + } + if (TIFFFieldSet(tif, FIELD_FILLORDER)) + { + fprintf(fd, " FillOrder: "); + switch (td->td_fillorder) + { + case FILLORDER_MSB2LSB: + fprintf(fd, "msb-to-lsb\n"); + break; + case FILLORDER_LSB2MSB: + fprintf(fd, "lsb-to-msb\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_fillorder, + td->td_fillorder); + break; + } + } + if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING)) + { + fprintf(fd, " YCbCr Subsampling: %" PRIu16 ", %" PRIu16 "\n", + td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1]); + } + if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING)) + { + fprintf(fd, " YCbCr Positioning: "); + switch (td->td_ycbcrpositioning) + { + case YCBCRPOSITION_CENTERED: + fprintf(fd, "centered\n"); + break; + case YCBCRPOSITION_COSITED: + fprintf(fd, "cosited\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + td->td_ycbcrpositioning, td->td_ycbcrpositioning); + break; + } + } + if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS)) + fprintf(fd, " Halftone Hints: light %" PRIu16 " dark %" PRIu16 "\n", + td->td_halftonehints[0], td->td_halftonehints[1]); + if (TIFFFieldSet(tif, FIELD_ORIENTATION)) + { + fprintf(fd, " Orientation: "); + if (td->td_orientation < NORIENTNAMES) + fprintf(fd, "%s\n", orientNames[td->td_orientation]); + else + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", td->td_orientation, + td->td_orientation); + } + if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL)) + fprintf(fd, " Samples/Pixel: %" PRIx16 "\n", td->td_samplesperpixel); + if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) + { + fprintf(fd, " Rows/Strip: "); + if (td->td_rowsperstrip == (uint32_t)-1) + fprintf(fd, "(infinite)\n"); + else + fprintf(fd, "%" PRIu32 "\n", td->td_rowsperstrip); + } + if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE)) + fprintf(fd, " Min Sample Value: %" PRIu16 "\n", td->td_minsamplevalue); + if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE)) + fprintf(fd, " Max Sample Value: %" PRIu16 "\n", td->td_maxsamplevalue); + if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE)) + { + int i; + int count = + (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; + fprintf(fd, " SMin Sample Value:"); + for (i = 0; i < count; ++i) + fprintf(fd, " %g", td->td_sminsamplevalue[i]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE)) + { + int i; + int count = + (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; + fprintf(fd, " SMax Sample Value:"); + for (i = 0; i < count; ++i) + fprintf(fd, " %g", td->td_smaxsamplevalue[i]); + fprintf(fd, "\n"); + } + if (TIFFFieldSet(tif, FIELD_PLANARCONFIG)) + { + fprintf(fd, " Planar Configuration: "); + switch (td->td_planarconfig) + { + case PLANARCONFIG_CONTIG: + fprintf(fd, "single image plane\n"); + break; + case PLANARCONFIG_SEPARATE: + fprintf(fd, "separate image planes\n"); + break; + default: + fprintf(fd, "%" PRIu16 " (0x%" PRIx16 ")\n", + td->td_planarconfig, td->td_planarconfig); + break; + } + } + if (TIFFFieldSet(tif, FIELD_PAGENUMBER)) + fprintf(fd, " Page Number: %" PRIu16 "-%" PRIu16 "\n", + td->td_pagenumber[0], td->td_pagenumber[1]); + if (TIFFFieldSet(tif, FIELD_COLORMAP)) + { + fprintf(fd, " Color Map: "); + if (flags & TIFFPRINT_COLORMAP) + { + fprintf(fd, "\n"); + n = 1L << td->td_bitspersample; + for (l = 0; l < n; l++) + fprintf(fd, " %5ld: %5" PRIu16 " %5" PRIu16 " %5" PRIu16 "\n", + l, td->td_colormap[0][l], td->td_colormap[1][l], + td->td_colormap[2][l]); + } + else + fprintf(fd, "(present)\n"); + } + if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE)) + { + int i; + fprintf(fd, " Reference Black/White:\n"); + for (i = 0; i < 3; i++) + fprintf(fd, " %2d: %5g %5g\n", i, + td->td_refblackwhite[2 * i + 0], + td->td_refblackwhite[2 * i + 1]); + } + if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION)) + { + fprintf(fd, " Transfer Function: "); + if (flags & TIFFPRINT_CURVES) + { + fprintf(fd, "\n"); + n = 1L << td->td_bitspersample; + for (l = 0; l < n; l++) + { + uint16_t i; + fprintf(fd, " %2ld: %5" PRIu16, l, + td->td_transferfunction[0][l]); + for (i = 1; + i < td->td_samplesperpixel - td->td_extrasamples && i < 3; + i++) + fprintf(fd, " %5" PRIu16, td->td_transferfunction[i][l]); + fputc('\n', fd); + } + } + else + fprintf(fd, "(present)\n"); + } + if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) + { + uint16_t i; + fprintf(fd, " SubIFD Offsets:"); + for (i = 0; i < td->td_nsubifd; i++) + fprintf(fd, " %5" PRIu64, td->td_subifd[i]); + fputc('\n', fd); + } + + /* + ** Custom tag support. + */ + { + int i; + short count; + + count = (short)TIFFGetTagListCount(tif); + for (i = 0; i < count; i++) { - fprintf(fd, " YCbCr Subsampling: %"PRIu16", %"PRIu16"\n", - td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] ); - } - if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) { - fprintf(fd, " YCbCr Positioning: "); - switch (td->td_ycbcrpositioning) { - case YCBCRPOSITION_CENTERED: - fprintf(fd, "centered\n"); - break; - case YCBCRPOSITION_COSITED: - fprintf(fd, "cosited\n"); - break; - default: - fprintf(fd, "%"PRIu16" (0x%"PRIx16")\n", - td->td_ycbcrpositioning, td->td_ycbcrpositioning); - break; - } - } - if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS)) - fprintf(fd, " Halftone Hints: light %"PRIu16" dark %"PRIu16"\n", - td->td_halftonehints[0], td->td_halftonehints[1]); - if (TIFFFieldSet(tif,FIELD_ORIENTATION)) { - fprintf(fd, " Orientation: "); - if (td->td_orientation < NORIENTNAMES) - fprintf(fd, "%s\n", orientNames[td->td_orientation]); - else - fprintf(fd, "%"PRIu16" (0x%"PRIx16")\n", - td->td_orientation, td->td_orientation); - } - if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL)) - fprintf(fd, " Samples/Pixel: %"PRIx16"\n", td->td_samplesperpixel); - if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) { - fprintf(fd, " Rows/Strip: "); - if (td->td_rowsperstrip == (uint32_t) -1) - fprintf(fd, "(infinite)\n"); - else - fprintf(fd, "%"PRIu32"\n", td->td_rowsperstrip); - } - if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE)) - fprintf(fd, " Min Sample Value: %"PRIu16"\n", td->td_minsamplevalue); - if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE)) - fprintf(fd, " Max Sample Value: %"PRIu16"\n", td->td_maxsamplevalue); - if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) { - int i; - int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; - fprintf(fd, " SMin Sample Value:"); - for (i = 0; i < count; ++i) - fprintf(fd, " %g", td->td_sminsamplevalue[i]); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) { - int i; - int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1; - fprintf(fd, " SMax Sample Value:"); - for (i = 0; i < count; ++i) - fprintf(fd, " %g", td->td_smaxsamplevalue[i]); - fprintf(fd, "\n"); - } - if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) { - fprintf(fd, " Planar Configuration: "); - switch (td->td_planarconfig) { - case PLANARCONFIG_CONTIG: - fprintf(fd, "single image plane\n"); - break; - case PLANARCONFIG_SEPARATE: - fprintf(fd, "separate image planes\n"); - break; - default: - fprintf(fd, "%"PRIu16" (0x%"PRIx16")\n", - td->td_planarconfig, td->td_planarconfig); - break; - } - } - if (TIFFFieldSet(tif,FIELD_PAGENUMBER)) - fprintf(fd, " Page Number: %"PRIu16"-%"PRIu16"\n", - td->td_pagenumber[0], td->td_pagenumber[1]); - if (TIFFFieldSet(tif,FIELD_COLORMAP)) { - fprintf(fd, " Color Map: "); - if (flags & TIFFPRINT_COLORMAP) { - fprintf(fd, "\n"); - n = 1L<<td->td_bitspersample; - for (l = 0; l < n; l++) - fprintf(fd, " %5ld: %5"PRIu16" %5"PRIu16" %5"PRIu16"\n", - l, - td->td_colormap[0][l], - td->td_colormap[1][l], - td->td_colormap[2][l]); - } else - fprintf(fd, "(present)\n"); - } - if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) { - int i; - fprintf(fd, " Reference Black/White:\n"); - for (i = 0; i < 3; i++) - fprintf(fd, " %2d: %5g %5g\n", i, - td->td_refblackwhite[2*i+0], - td->td_refblackwhite[2*i+1]); - } - if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) { - fprintf(fd, " Transfer Function: "); - if (flags & TIFFPRINT_CURVES) { - fprintf(fd, "\n"); - n = 1L<<td->td_bitspersample; - for (l = 0; l < n; l++) { - uint16_t i; - fprintf(fd, " %2ld: %5"PRIu16, - l, td->td_transferfunction[0][l]); - for (i = 1; i < td->td_samplesperpixel - td->td_extrasamples && i < 3; i++) - fprintf(fd, " %5"PRIu16, - td->td_transferfunction[i][l]); - fputc('\n', fd); - } - } else - fprintf(fd, "(present)\n"); - } - if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) { - uint16_t i; - fprintf(fd, " SubIFD Offsets:"); - for (i = 0; i < td->td_nsubifd; i++) - fprintf(fd, " %5"PRIu64, - td->td_subifd[i]); - fputc('\n', fd); - } - - /* - ** Custom tag support. - */ - { - int i; - short count; - - count = (short) TIFFGetTagListCount(tif); - for(i = 0; i < count; i++) { - uint32_t tag = TIFFGetTagListEntry(tif, i); - const TIFFField *fip; - uint32_t value_count; - int mem_alloc = 0; - void *raw_data = NULL; - uint16_t dotrange[2]; /* must be kept in that scope and not moved in the below TIFFTAG_DOTRANGE specific case */ - - fip = TIFFFieldWithTag(tif, tag); - if(fip == NULL) - continue; - - if(fip->field_passcount) { - if (fip->field_readcount == TIFF_VARIABLE2 ) { - if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) - continue; - } else if (fip->field_readcount == TIFF_VARIABLE ) { - uint16_t small_value_count; - if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1) - continue; - value_count = small_value_count; - } else { - assert (fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2); - continue; - } - } else { - if (fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2) - value_count = 1; - else if (fip->field_readcount == TIFF_SPP) - value_count = td->td_samplesperpixel; - else - value_count = fip->field_readcount; - if (fip->field_tag == TIFFTAG_DOTRANGE - && strcmp(fip->field_name,"DotRange") == 0) { - /* TODO: This is an evil exception and should not have been - handled this way ... likely best if we move it into - the directory structure with an explicit field in - libtiff 4.1 and assign it a FIELD_ value */ - raw_data = dotrange; - TIFFGetField(tif, tag, dotrange+0, dotrange+1); - } else if (fip->field_type == TIFF_ASCII - || fip->field_readcount == TIFF_VARIABLE - || fip->field_readcount == TIFF_VARIABLE2 - || fip->field_readcount == TIFF_SPP - || value_count > 1) { - if(TIFFGetField(tif, tag, &raw_data) != 1) - continue; - } else { - /*--: Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */ - int tv_size = TIFFFieldSetGetSize(fip); - raw_data = _TIFFmallocExt(tif, - tv_size - * value_count); - mem_alloc = 1; - if(TIFFGetField(tif, tag, raw_data) != 1) { - _TIFFfreeExt(tif, raw_data); - continue; - } - } - } - - /* - * Catch the tags which needs to be specially handled - * and pretty print them. If tag not handled in - * _TIFFPrettyPrintField() fall down and print it as - * any other tag. - */ - if (raw_data != NULL && !_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data)) - _TIFFPrintField(fd, fip, value_count, raw_data); - - if(mem_alloc) - _TIFFfreeExt(tif, raw_data); - } - } - - if (tif->tif_tagmethods.printdir) - (*tif->tif_tagmethods.printdir)(tif, fd, flags); - - if ((flags & TIFFPRINT_STRIPS) && - TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) { - uint32_t s; - - fprintf(fd, " %"PRIu32" %s:\n", - td->td_nstrips, - isTiled(tif) ? "Tiles" : "Strips"); - for (s = 0; s < td->td_nstrips; s++) - fprintf(fd, " %3"PRIu32": [%8"PRIu64", %8"PRIu64"]\n", - s, - TIFFGetStrileOffset(tif, s), - TIFFGetStrileByteCount(tif, s)); - } + uint32_t tag = TIFFGetTagListEntry(tif, i); + const TIFFField *fip; + uint32_t value_count; + int mem_alloc = 0; + void *raw_data = NULL; + uint16_t dotrange[2]; /* must be kept in that scope and not moved in + the below TIFFTAG_DOTRANGE specific case */ + + fip = TIFFFieldWithTag(tif, tag); + if (fip == NULL) + continue; + + if (fip->field_passcount) + { + if (fip->field_readcount == TIFF_VARIABLE2) + { + if (TIFFGetField(tif, tag, &value_count, &raw_data) != 1) + continue; + } + else if (fip->field_readcount == TIFF_VARIABLE) + { + uint16_t small_value_count; + if (TIFFGetField(tif, tag, &small_value_count, &raw_data) != + 1) + continue; + value_count = small_value_count; + } + else + { + assert(fip->field_readcount == TIFF_VARIABLE || + fip->field_readcount == TIFF_VARIABLE2); + continue; + } + } + else + { + if (fip->field_readcount == TIFF_VARIABLE || + fip->field_readcount == TIFF_VARIABLE2) + value_count = 1; + else if (fip->field_readcount == TIFF_SPP) + value_count = td->td_samplesperpixel; + else + value_count = fip->field_readcount; + if (fip->field_tag == TIFFTAG_DOTRANGE && + strcmp(fip->field_name, "DotRange") == 0) + { + /* TODO: This is an evil exception and should not have been + handled this way ... likely best if we move it into + the directory structure with an explicit field in + libtiff 4.1 and assign it a FIELD_ value */ + raw_data = dotrange; + TIFFGetField(tif, tag, dotrange + 0, dotrange + 1); + } + else if (fip->field_type == TIFF_ASCII || + fip->field_readcount == TIFF_VARIABLE || + fip->field_readcount == TIFF_VARIABLE2 || + fip->field_readcount == TIFF_SPP || value_count > 1) + { + if (TIFFGetField(tif, tag, &raw_data) != 1) + continue; + } + else + { + /*--: Rational2Double: For Rationals evaluate + * "set_field_type" to determine internal storage size. */ + int tv_size = TIFFFieldSetGetSize(fip); + raw_data = _TIFFmallocExt(tif, tv_size * value_count); + mem_alloc = 1; + if (TIFFGetField(tif, tag, raw_data) != 1) + { + _TIFFfreeExt(tif, raw_data); + continue; + } + } + } + + /* + * Catch the tags which needs to be specially handled + * and pretty print them. If tag not handled in + * _TIFFPrettyPrintField() fall down and print it as + * any other tag. + */ + if (raw_data != NULL && + !_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, + raw_data)) + _TIFFPrintField(fd, fip, value_count, raw_data); + + if (mem_alloc) + _TIFFfreeExt(tif, raw_data); + } + } + + if (tif->tif_tagmethods.printdir) + (*tif->tif_tagmethods.printdir)(tif, fd, flags); + + if ((flags & TIFFPRINT_STRIPS) && TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) + { + uint32_t s; + + fprintf(fd, " %" PRIu32 " %s:\n", td->td_nstrips, + isTiled(tif) ? "Tiles" : "Strips"); + for (s = 0; s < td->td_nstrips; s++) + fprintf(fd, " %3" PRIu32 ": [%8" PRIu64 ", %8" PRIu64 "]\n", s, + TIFFGetStrileOffset(tif, s), + TIFFGetStrileByteCount(tif, s)); + } } -void -_TIFFprintAscii(FILE* fd, const char* cp) +void _TIFFprintAscii(FILE *fd, const char *cp) { - _TIFFprintAsciiBounded( fd, cp, strlen(cp)); + _TIFFprintAsciiBounded(fd, cp, strlen(cp)); } -static void -_TIFFprintAsciiBounded(FILE* fd, const char* cp, size_t max_chars) +static void _TIFFprintAsciiBounded(FILE *fd, const char *cp, size_t max_chars) { - for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) { - const char* tp; - - if (isprint((int)*cp)) { - fputc(*cp, fd); - continue; - } - for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++) - if (*tp++ == *cp) - break; - if (*tp) - fprintf(fd, "\\%c", *tp); - else - fprintf(fd, "\\%03o", *cp & 0xff); - } + for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) + { + const char *tp; + + if (isprint((int)*cp)) + { + fputc(*cp, fd); + continue; + } + for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++) + if (*tp++ == *cp) + break; + if (*tp) + fprintf(fd, "\\%c", *tp); + else + fprintf(fd, "\\%03o", *cp & 0xff); + } } -void -_TIFFprintAsciiTag(FILE* fd, const char* name, const char* value) +void _TIFFprintAsciiTag(FILE *fd, const char *name, const char *value) { - fprintf(fd, " %s: \"", name); - _TIFFprintAscii(fd, value); - fprintf(fd, "\"\n"); + fprintf(fd, " %s: \"", name); + _TIFFprintAscii(fd, value); + fprintf(fd, "\"\n"); } diff --git a/libtiff/tif_read.c b/libtiff/tif_read.c index 108bdeba..4fec8396 100644 --- a/libtiff/tif_read.c +++ b/libtiff/tif_read.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,269 +29,273 @@ #include "tiffiop.h" #include <stdio.h> -int TIFFFillStrip(TIFF* tif, uint32_t strip); -int TIFFFillTile(TIFF* tif, uint32_t tile); -static int TIFFStartStrip(TIFF* tif, uint32_t strip); -static int TIFFStartTile(TIFF* tif, uint32_t tile); -static int TIFFCheckRead(TIFF*, int); -static tmsize_t -TIFFReadRawStrip1(TIFF* tif, uint32_t strip, void* buf, tmsize_t size, const char* module); -static tmsize_t -TIFFReadRawTile1(TIFF* tif, uint32_t tile, void* buf, tmsize_t size, const char* module); +int TIFFFillStrip(TIFF *tif, uint32_t strip); +int TIFFFillTile(TIFF *tif, uint32_t tile); +static int TIFFStartStrip(TIFF *tif, uint32_t strip); +static int TIFFStartTile(TIFF *tif, uint32_t tile); +static int TIFFCheckRead(TIFF *, int); +static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf, + tmsize_t size, const char *module); +static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf, + tmsize_t size, const char *module); -#define NOSTRIP ((uint32_t)(-1)) /* undefined state */ -#define NOTILE ((uint32_t)(-1)) /* undefined state */ +#define NOSTRIP ((uint32_t)(-1)) /* undefined state */ +#define NOTILE ((uint32_t)(-1)) /* undefined state */ #define INITIAL_THRESHOLD (1024 * 1024) #define THRESHOLD_MULTIPLIER 10 -#define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD) +#define MAX_THRESHOLD \ + (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \ + INITIAL_THRESHOLD) #define TIFF_INT64_MAX ((((int64_t)0x7FFFFFFF) << 32) | 0xFFFFFFFF) /* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset' * Returns 1 in case of success, 0 otherwise. */ -static int TIFFReadAndRealloc(TIFF* tif, tmsize_t size, - tmsize_t rawdata_offset, +static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset, int is_strip, uint32_t strip_or_tile, - const char* module ) + const char *module) { #if SIZEOF_SIZE_T == 8 - tmsize_t threshold = INITIAL_THRESHOLD; + tmsize_t threshold = INITIAL_THRESHOLD; #endif - tmsize_t already_read = 0; - + tmsize_t already_read = 0; #if SIZEOF_SIZE_T != 8 - /* On 32 bit processes, if the request is large enough, check against */ - /* file size */ - if( size > 1000 * 1000 * 1000 ) + /* On 32 bit processes, if the request is large enough, check against */ + /* file size */ + if (size > 1000 * 1000 * 1000) + { + uint64_t filesize = TIFFGetFileSize(tif); + if ((uint64_t)size >= filesize) { - uint64_t filesize = TIFFGetFileSize(tif); - if((uint64_t)size >= filesize ) - { - TIFFErrorExtR(tif, module, - "Chunk size requested is larger than file size."); - return 0; - } + TIFFErrorExtR(tif, module, + "Chunk size requested is larger than file size."); + return 0; } + } #endif - /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ - /* so as to avoid allocating too much memory in case the file is too */ - /* short. We could ask for the file size, but this might be */ - /* expensive with some I/O layers (think of reading a gzipped file) */ - /* Restrict to 64 bit processes, so as to avoid reallocs() */ - /* on 32 bit processes where virtual memory is scarce. */ - while( already_read < size ) - { - tmsize_t bytes_read; - tmsize_t to_read = size - already_read; + /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */ + /* so as to avoid allocating too much memory in case the file is too */ + /* short. We could ask for the file size, but this might be */ + /* expensive with some I/O layers (think of reading a gzipped file) */ + /* Restrict to 64 bit processes, so as to avoid reallocs() */ + /* on 32 bit processes where virtual memory is scarce. */ + while (already_read < size) + { + tmsize_t bytes_read; + tmsize_t to_read = size - already_read; #if SIZEOF_SIZE_T == 8 - if( to_read >= threshold && threshold < MAX_THRESHOLD && - already_read + to_read + rawdata_offset > tif->tif_rawdatasize ) - { - to_read = threshold; - threshold *= THRESHOLD_MULTIPLIER; - } + if (to_read >= threshold && threshold < MAX_THRESHOLD && + already_read + to_read + rawdata_offset > tif->tif_rawdatasize) + { + to_read = threshold; + threshold *= THRESHOLD_MULTIPLIER; + } #endif - if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize) { - uint8_t* new_rawdata; - assert((tif->tif_flags & TIFF_MYBUFFER) != 0); - tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64( - (uint64_t)already_read + to_read + rawdata_offset, 1024); - if (tif->tif_rawdatasize==0) { - TIFFErrorExtR(tif, module, - "Invalid buffer size"); - return 0; - } - new_rawdata = (uint8_t*) _TIFFrealloc( - tif->tif_rawdata, tif->tif_rawdatasize); - if( new_rawdata == 0 ) - { - TIFFErrorExtR(tif, module, - "No space for data buffer at scanline %"PRIu32, - tif->tif_row); - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = 0; - tif->tif_rawdatasize = 0; - return 0; - } - tif->tif_rawdata = new_rawdata; + if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize) + { + uint8_t *new_rawdata; + assert((tif->tif_flags & TIFF_MYBUFFER) != 0); + tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64( + (uint64_t)already_read + to_read + rawdata_offset, 1024); + if (tif->tif_rawdatasize == 0) + { + TIFFErrorExtR(tif, module, "Invalid buffer size"); + return 0; } - if( tif->tif_rawdata == NULL ) + new_rawdata = + (uint8_t *)_TIFFrealloc(tif->tif_rawdata, tif->tif_rawdatasize); + if (new_rawdata == 0) { - /* should not happen in practice but helps CoverityScan */ + TIFFErrorExtR(tif, module, + "No space for data buffer at scanline %" PRIu32, + tif->tif_row); + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = 0; + tif->tif_rawdatasize = 0; return 0; } + tif->tif_rawdata = new_rawdata; + } + if (tif->tif_rawdata == NULL) + { + /* should not happen in practice but helps CoverityScan */ + return 0; + } - bytes_read = TIFFReadFile(tif, - tif->tif_rawdata + rawdata_offset + already_read, to_read); - already_read += bytes_read; - if (bytes_read != to_read) { - memset( tif->tif_rawdata + rawdata_offset + already_read, 0, - tif->tif_rawdatasize - rawdata_offset - already_read ); - if( is_strip ) - { - TIFFErrorExtR(tif, module, - "Read error at scanline %"PRIu32"; got %"TIFF_SSIZE_FORMAT" bytes, " - "expected %"TIFF_SSIZE_FORMAT, - tif->tif_row, - already_read, - size); - } - else - { - TIFFErrorExtR(tif, module, - "Read error at row %"PRIu32", col %"PRIu32", tile %"PRIu32"; " - "got %"TIFF_SSIZE_FORMAT" bytes, expected %"TIFF_SSIZE_FORMAT"", - tif->tif_row, - tif->tif_col, - strip_or_tile, - already_read, - size); - } - return 0; + bytes_read = TIFFReadFile( + tif, tif->tif_rawdata + rawdata_offset + already_read, to_read); + already_read += bytes_read; + if (bytes_read != to_read) + { + memset(tif->tif_rawdata + rawdata_offset + already_read, 0, + tif->tif_rawdatasize - rawdata_offset - already_read); + if (is_strip) + { + TIFFErrorExtR(tif, module, + "Read error at scanline %" PRIu32 + "; got %" TIFF_SSIZE_FORMAT " bytes, " + "expected %" TIFF_SSIZE_FORMAT, + tif->tif_row, already_read, size); } + else + { + TIFFErrorExtR(tif, module, + "Read error at row %" PRIu32 ", col %" PRIu32 + ", tile %" PRIu32 "; " + "got %" TIFF_SSIZE_FORMAT + " bytes, expected %" TIFF_SSIZE_FORMAT "", + tif->tif_row, tif->tif_col, strip_or_tile, + already_read, size); + } + return 0; } - return 1; + } + return 1; } - -static int -TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) +static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead, + int restart) { - static const char module[] = "TIFFFillStripPartial"; - register TIFFDirectory *td = &tif->tif_dir; - tmsize_t unused_data; - uint64_t read_offset; - tmsize_t to_read; - tmsize_t read_ahead_mod; - /* tmsize_t bytecountm; */ + static const char module[] = "TIFFFillStripPartial"; + register TIFFDirectory *td = &tif->tif_dir; + tmsize_t unused_data; + uint64_t read_offset; + tmsize_t to_read; + tmsize_t read_ahead_mod; + /* tmsize_t bytecountm; */ + + /* + * Expand raw data buffer, if needed, to hold data + * strip coming from file (perhaps should set upper + * bound on the size of a buffer we'll use?). + */ + + /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */ + + /* Not completely sure where the * 2 comes from, but probably for */ + /* an exponentional growth strategy of tif_rawdatasize */ + if (read_ahead < TIFF_TMSIZE_T_MAX / 2) + read_ahead_mod = read_ahead * 2; + else + read_ahead_mod = read_ahead; + if (read_ahead_mod > tif->tif_rawdatasize) + { + assert(restart); - /* - * Expand raw data buffer, if needed, to hold data - * strip coming from file (perhaps should set upper - * bound on the size of a buffer we'll use?). - */ + tif->tif_curstrip = NOSTRIP; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) + { + TIFFErrorExtR(tif, module, + "Data buffer too small to hold part of strip %d", + strip); + return (0); + } + } - /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */ + if (restart) + { + tif->tif_rawdataloaded = 0; + tif->tif_rawdataoff = 0; + } - /* Not completely sure where the * 2 comes from, but probably for */ - /* an exponentional growth strategy of tif_rawdatasize */ - if( read_ahead < TIFF_TMSIZE_T_MAX / 2 ) - read_ahead_mod = read_ahead * 2; - else - read_ahead_mod = read_ahead; - if (read_ahead_mod > tif->tif_rawdatasize) { - assert( restart ); - - tif->tif_curstrip = NOSTRIP; - if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - TIFFErrorExtR(tif, module, - "Data buffer too small to hold part of strip %d", - strip); - return (0); - } - } + /* + ** If we are reading more data, move any unused data to the + ** start of the buffer. + */ + if (tif->tif_rawdataloaded > 0) + unused_data = + tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata); + else + unused_data = 0; - if( restart ) - { - tif->tif_rawdataloaded = 0; - tif->tif_rawdataoff = 0; - } + if (unused_data > 0) + { + assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); + memmove(tif->tif_rawdata, tif->tif_rawcp, unused_data); + } - /* - ** If we are reading more data, move any unused data to the - ** start of the buffer. - */ - if( tif->tif_rawdataloaded > 0 ) - unused_data = tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata); - else - unused_data = 0; - - if( unused_data > 0 ) - { - assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); - memmove( tif->tif_rawdata, tif->tif_rawcp, unused_data ); - } + /* + ** Seek to the point in the file where more data should be read. + */ + read_offset = TIFFGetStrileOffset(tif, strip) + tif->tif_rawdataoff + + tif->tif_rawdataloaded; - /* - ** Seek to the point in the file where more data should be read. - */ - read_offset = TIFFGetStrileOffset(tif, strip) - + tif->tif_rawdataoff + tif->tif_rawdataloaded; + if (!SeekOK(tif, read_offset)) + { + TIFFErrorExtR(tif, module, + "Seek error at scanline %" PRIu32 ", strip %d", + tif->tif_row, strip); + return 0; + } - if (!SeekOK(tif, read_offset)) { - TIFFErrorExtR(tif, module, - "Seek error at scanline %"PRIu32", strip %d", - tif->tif_row, strip); - return 0; - } + /* + ** How much do we want to read? + */ + if (read_ahead_mod > tif->tif_rawdatasize) + to_read = read_ahead_mod - unused_data; + else + to_read = tif->tif_rawdatasize - unused_data; + if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, strip) - + tif->tif_rawdataoff - tif->tif_rawdataloaded) + { + to_read = (tmsize_t)TIFFGetStrileByteCount(tif, strip) - + tif->tif_rawdataoff - tif->tif_rawdataloaded; + } - /* - ** How much do we want to read? - */ - if( read_ahead_mod > tif->tif_rawdatasize ) - to_read = read_ahead_mod - unused_data; - else - to_read = tif->tif_rawdatasize - unused_data; - if((uint64_t) to_read > TIFFGetStrileByteCount(tif, strip) - - tif->tif_rawdataoff - tif->tif_rawdataloaded ) - { - to_read = (tmsize_t) TIFFGetStrileByteCount(tif, strip) - - tif->tif_rawdataoff - tif->tif_rawdataloaded; - } + assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); + if (!TIFFReadAndRealloc(tif, to_read, unused_data, 1, /* is_strip */ + 0, /* strip_or_tile */ + module)) + { + return 0; + } - assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); - if( !TIFFReadAndRealloc( tif, to_read, unused_data, - 1, /* is_strip */ - 0, /* strip_or_tile */ - module) ) - { - return 0; - } + tif->tif_rawdataoff = + tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data; + tif->tif_rawdataloaded = unused_data + to_read; - tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ; - tif->tif_rawdataloaded = unused_data + to_read; + tif->tif_rawcc = tif->tif_rawdataloaded; + tif->tif_rawcp = tif->tif_rawdata; - tif->tif_rawcc = tif->tif_rawdataloaded; - tif->tif_rawcp = tif->tif_rawdata; - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) { - assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); - TIFFReverseBits(tif->tif_rawdata + unused_data, to_read ); - } + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + { + assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0); + TIFFReverseBits(tif->tif_rawdata + unused_data, to_read); + } - /* - ** When starting a strip from the beginning we need to - ** restart the decoder. - */ - if( restart ) - { + /* + ** When starting a strip from the beginning we need to + ** restart the decoder. + */ + if (restart) + { #ifdef JPEG_SUPPORT - /* A bit messy since breaks the codec abstraction. Ultimately */ - /* there should be a function pointer for that, but it seems */ - /* only JPEG is affected. */ - /* For JPEG, if there are multiple scans (can generally be known */ - /* with the read_ahead used), we need to read the whole strip */ - if( tif->tif_dir.td_compression==COMPRESSION_JPEG && - (uint64_t)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip) ) + /* A bit messy since breaks the codec abstraction. Ultimately */ + /* there should be a function pointer for that, but it seems */ + /* only JPEG is affected. */ + /* For JPEG, if there are multiple scans (can generally be known */ + /* with the read_ahead used), we need to read the whole strip */ + if (tif->tif_dir.td_compression == COMPRESSION_JPEG && + (uint64_t)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip)) + { + if (TIFFJPEGIsFullStripRequired(tif)) { - if( TIFFJPEGIsFullStripRequired(tif) ) - { - return TIFFFillStrip(tif, strip); - } + return TIFFFillStrip(tif, strip); } + } #endif - return TIFFStartStrip(tif, strip); - } - else - { - return 1; - } + return TIFFStartStrip(tif, strip); + } + else + { + return 1; + } } /* @@ -302,159 +306,165 @@ TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) * and avoid reading the whole compressed raw data for big * strips. */ -static int -TIFFSeek(TIFF* tif, uint32_t row, uint16_t sample ) +static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample) { - register TIFFDirectory *td = &tif->tif_dir; - uint32_t strip; - int whole_strip; - tmsize_t read_ahead = 0; - - /* - ** Establish what strip we are working from. - */ - if (row >= td->td_imagelength) { /* out of range */ - TIFFErrorExtR(tif, tif->tif_name, - "%"PRIu32": Row out of range, max %"PRIu32"", - row, - td->td_imagelength); - return (0); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - if (sample >= td->td_samplesperpixel) { - TIFFErrorExtR(tif, tif->tif_name, - "%"PRIu16": Sample out of range, max %"PRIu16"", - sample, td->td_samplesperpixel); - return (0); - } - strip = (uint32_t)sample * td->td_stripsperimage + row / td->td_rowsperstrip; - } else - strip = row / td->td_rowsperstrip; + register TIFFDirectory *td = &tif->tif_dir; + uint32_t strip; + int whole_strip; + tmsize_t read_ahead = 0; + + /* + ** Establish what strip we are working from. + */ + if (row >= td->td_imagelength) + { /* out of range */ + TIFFErrorExtR(tif, tif->tif_name, + "%" PRIu32 ": Row out of range, max %" PRIu32 "", row, + td->td_imagelength); + return (0); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + if (sample >= td->td_samplesperpixel) + { + TIFFErrorExtR(tif, tif->tif_name, + "%" PRIu16 ": Sample out of range, max %" PRIu16 "", + sample, td->td_samplesperpixel); + return (0); + } + strip = (uint32_t)sample * td->td_stripsperimage + + row / td->td_rowsperstrip; + } + else + strip = row / td->td_rowsperstrip; /* * Do we want to treat this strip as one whole chunk or * read it a few lines at a time? */ #if defined(CHUNKY_STRIP_READ_SUPPORT) - whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 - || isMapped(tif); - if( td->td_compression == COMPRESSION_LERC || - td->td_compression == COMPRESSION_JBIG ) - { - /* Ideally plugins should have a way to declare they don't support - * chunk strip */ - whole_strip = 1; - } -#else + whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 || isMapped(tif); + if (td->td_compression == COMPRESSION_LERC || + td->td_compression == COMPRESSION_JBIG) + { + /* Ideally plugins should have a way to declare they don't support + * chunk strip */ whole_strip = 1; + } +#else + whole_strip = 1; #endif - - if( !whole_strip ) + + if (!whole_strip) + { + /* 16 is for YCbCr mode where we may need to read 16 */ + /* lines at a time to get a decompressed line, and 5000 */ + /* is some constant value, for example for JPEG tables */ + if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 && + tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000) { - /* 16 is for YCbCr mode where we may need to read 16 */ - /* lines at a time to get a decompressed line, and 5000 */ - /* is some constant value, for example for JPEG tables */ - if( tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 && - tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000 ) - { - read_ahead = tif->tif_scanlinesize * 16 + 5000; - } - else - { - read_ahead = tif->tif_scanlinesize; - } + read_ahead = tif->tif_scanlinesize * 16 + 5000; + } + else + { + read_ahead = tif->tif_scanlinesize; + } + } + + /* + * If we haven't loaded this strip, do so now, possibly + * only reading the first part. + */ + if (strip != tif->tif_curstrip) + { /* different strip, refill */ + + if (whole_strip) + { + if (!TIFFFillStrip(tif, strip)) + return (0); + } + else + { + if (!TIFFFillStripPartial(tif, strip, read_ahead, 1)) + return 0; + } + } + + /* + ** If we already have some data loaded, do we need to read some more? + */ + else if (!whole_strip) + { + if (((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < + read_ahead && + (uint64_t)tif->tif_rawdataoff + tif->tif_rawdataloaded < + TIFFGetStrileByteCount(tif, strip)) + { + if (!TIFFFillStripPartial(tif, strip, read_ahead, 0)) + return 0; } + } + if (row < tif->tif_row) + { /* - * If we haven't loaded this strip, do so now, possibly - * only reading the first part. + * Moving backwards within the same strip: backup + * to the start and then decode forward (below). + * + * NB: If you're planning on lots of random access within a + * strip, it's better to just read and decode the entire + * strip, and then access the decoded data in a random fashion. */ - if (strip != tif->tif_curstrip) { /* different strip, refill */ - - if( whole_strip ) - { - if (!TIFFFillStrip(tif, strip)) - return (0); - } - else - { - if( !TIFFFillStripPartial(tif,strip,read_ahead,1) ) - return 0; - } - } - /* - ** If we already have some data loaded, do we need to read some more? - */ - else if( !whole_strip ) + if (tif->tif_rawdataoff != 0) { - if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead - && (uint64_t) tif->tif_rawdataoff + tif->tif_rawdataloaded < TIFFGetStrileByteCount(tif, strip) ) - { - if( !TIFFFillStripPartial(tif,strip,read_ahead,0) ) - return 0; - } + if (!TIFFFillStripPartial(tif, strip, read_ahead, 1)) + return 0; + } + else + { + if (!TIFFStartStrip(tif, strip)) + return (0); } + } - if (row < tif->tif_row) { - /* - * Moving backwards within the same strip: backup - * to the start and then decode forward (below). - * - * NB: If you're planning on lots of random access within a - * strip, it's better to just read and decode the entire - * strip, and then access the decoded data in a random fashion. - */ - - if( tif->tif_rawdataoff != 0 ) - { - if( !TIFFFillStripPartial(tif,strip,read_ahead,1) ) - return 0; - } - else - { - if (!TIFFStartStrip(tif, strip)) - return (0); - } - } - - if (row != tif->tif_row) { - /* - * Seek forward to the desired row. - */ - - /* TODO: Will this really work with partial buffers? */ - - if (!(*tif->tif_seek)(tif, row - tif->tif_row)) - return (0); - tif->tif_row = row; - } - - return (1); + if (row != tif->tif_row) + { + /* + * Seek forward to the desired row. + */ + + /* TODO: Will this really work with partial buffers? */ + + if (!(*tif->tif_seek)(tif, row - tif->tif_row)) + return (0); + tif->tif_row = row; + } + + return (1); } -int -TIFFReadScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample) +int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) { - int e; - - if (!TIFFCheckRead(tif, 0)) - return (-1); - if( (e = TIFFSeek(tif, row, sample)) != 0) { - /* - * Decompress desired row into user buffer. - */ - e = (*tif->tif_decoderow) - (tif, (uint8_t*) buf, tif->tif_scanlinesize, sample); - - /* we are now poised at the beginning of the next row */ - tif->tif_row = row + 1; - - if (e) - (*tif->tif_postdecode)(tif, (uint8_t*) buf, - tif->tif_scanlinesize); - } - return (e > 0 ? 1 : -1); + int e; + + if (!TIFFCheckRead(tif, 0)) + return (-1); + if ((e = TIFFSeek(tif, row, sample)) != 0) + { + /* + * Decompress desired row into user buffer. + */ + e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize, + sample); + + /* we are now poised at the beginning of the next row */ + tif->tif_row = row + 1; + + if (e) + (*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize); + } + return (e > 0 ? 1 : -1); } /* @@ -462,426 +472,436 @@ TIFFReadScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample) * rows in the strip (check for truncated last strip on any * of the separations). */ -static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF* tif, uint32_t strip, uint16_t* pplane) +static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF *tif, uint32_t strip, + uint16_t *pplane) { - static const char module[] = "TIFFReadEncodedStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint32_t rowsperstrip; - uint32_t stripsperplane; - uint32_t stripinplane; - uint32_t rows; - tmsize_t stripsize; - if (!TIFFCheckRead(tif,0)) - return((tmsize_t)(-1)); - if (strip>=td->td_nstrips) - { - TIFFErrorExtR(tif,module, - "%"PRIu32": Strip out of range, max %"PRIu32, strip, - td->td_nstrips); - return((tmsize_t)(-1)); - } - - rowsperstrip=td->td_rowsperstrip; - if (rowsperstrip>td->td_imagelength) - rowsperstrip=td->td_imagelength; - stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); - stripinplane=(strip%stripsperplane); - if( pplane ) *pplane=(uint16_t)(strip / stripsperplane); - rows=td->td_imagelength-stripinplane*rowsperstrip; - if (rows>rowsperstrip) - rows=rowsperstrip; - stripsize=TIFFVStripSize(tif,rows); - if (stripsize==0) - return((tmsize_t)(-1)); - return stripsize; + static const char module[] = "TIFFReadEncodedStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint32_t rowsperstrip; + uint32_t stripsperplane; + uint32_t stripinplane; + uint32_t rows; + tmsize_t stripsize; + if (!TIFFCheckRead(tif, 0)) + return ((tmsize_t)(-1)); + if (strip >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, + "%" PRIu32 ": Strip out of range, max %" PRIu32, strip, + td->td_nstrips); + return ((tmsize_t)(-1)); + } + + rowsperstrip = td->td_rowsperstrip; + if (rowsperstrip > td->td_imagelength) + rowsperstrip = td->td_imagelength; + stripsperplane = + TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); + stripinplane = (strip % stripsperplane); + if (pplane) + *pplane = (uint16_t)(strip / stripsperplane); + rows = td->td_imagelength - stripinplane * rowsperstrip; + if (rows > rowsperstrip) + rows = rowsperstrip; + stripsize = TIFFVStripSize(tif, rows); + if (stripsize == 0) + return ((tmsize_t)(-1)); + return stripsize; } /* * Read a strip of data and decompress the specified * amount into the user-supplied buffer. */ -tmsize_t -TIFFReadEncodedStrip(TIFF* tif, uint32_t strip, void* buf, tmsize_t size) +tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf, + tmsize_t size) { - static const char module[] = "TIFFReadEncodedStrip"; - TIFFDirectory *td = &tif->tif_dir; - tmsize_t stripsize; - uint16_t plane; + static const char module[] = "TIFFReadEncodedStrip"; + TIFFDirectory *td = &tif->tif_dir; + tmsize_t stripsize; + uint16_t plane; - stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane); - if (stripsize==((tmsize_t)(-1))) - return((tmsize_t)(-1)); + stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane); + if (stripsize == ((tmsize_t)(-1))) + return ((tmsize_t)(-1)); /* shortcut to avoid an extra memcpy() */ - if( td->td_compression == COMPRESSION_NONE && - size!=(tmsize_t)(-1) && size >= stripsize && - !isMapped(tif) && - ((tif->tif_flags&TIFF_NOREADRAW)==0) ) + if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) && + size >= stripsize && !isMapped(tif) && + ((tif->tif_flags & TIFF_NOREADRAW) == 0)) { if (TIFFReadRawStrip1(tif, strip, buf, stripsize, module) != stripsize) return ((tmsize_t)(-1)); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(buf,stripsize); + TIFFReverseBits(buf, stripsize); - (*tif->tif_postdecode)(tif,buf,stripsize); + (*tif->tif_postdecode)(tif, buf, stripsize); return (stripsize); } - if ((size!=(tmsize_t)(-1))&&(size<stripsize)) - stripsize=size; - if (!TIFFFillStrip(tif,strip)) - return((tmsize_t)(-1)); - if ((*tif->tif_decodestrip)(tif,buf,stripsize,plane)<=0) - return((tmsize_t)(-1)); - (*tif->tif_postdecode)(tif,buf,stripsize); - return(stripsize); + if ((size != (tmsize_t)(-1)) && (size < stripsize)) + stripsize = size; + if (!TIFFFillStrip(tif, strip)) + return ((tmsize_t)(-1)); + if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0) + return ((tmsize_t)(-1)); + (*tif->tif_postdecode)(tif, buf, stripsize); + return (stripsize); } -/* Variant of TIFFReadEncodedStrip() that does - * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after TIFFFillStrip() has - * succeeded. This avoid excessive memory allocation in case of truncated - * file. +/* Variant of TIFFReadEncodedStrip() that does + * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after + * TIFFFillStrip() has succeeded. This avoid excessive memory allocation in case + * of truncated file. * * calls regular TIFFReadEncodedStrip() if *buf != NULL */ -tmsize_t -_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32_t strip, - void **buf, tmsize_t bufsizetoalloc, - tmsize_t size_to_read) +tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip, + void **buf, + tmsize_t bufsizetoalloc, + tmsize_t size_to_read) { tmsize_t this_stripsize; uint16_t plane; - if( *buf != NULL ) + if (*buf != NULL) { return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read); } - this_stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane); - if (this_stripsize==((tmsize_t)(-1))) - return((tmsize_t)(-1)); + this_stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane); + if (this_stripsize == ((tmsize_t)(-1))) + return ((tmsize_t)(-1)); - if ((size_to_read!=(tmsize_t)(-1))&&(size_to_read<this_stripsize)) - this_stripsize=size_to_read; - if (!TIFFFillStrip(tif,strip)) - return((tmsize_t)(-1)); + if ((size_to_read != (tmsize_t)(-1)) && (size_to_read < this_stripsize)) + this_stripsize = size_to_read; + if (!TIFFFillStrip(tif, strip)) + return ((tmsize_t)(-1)); *buf = _TIFFmallocExt(tif, bufsizetoalloc); - if (*buf == NULL) { - TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer"); - return((tmsize_t)(-1)); + if (*buf == NULL) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer"); + return ((tmsize_t)(-1)); } _TIFFmemset(*buf, 0, bufsizetoalloc); - if ((*tif->tif_decodestrip)(tif,*buf,this_stripsize,plane)<=0) - return((tmsize_t)(-1)); - (*tif->tif_postdecode)(tif,*buf,this_stripsize); - return(this_stripsize); - - -} - -static tmsize_t -TIFFReadRawStrip1(TIFF* tif, uint32_t strip, void* buf, tmsize_t size, - const char* module) -{ - assert((tif->tif_flags&TIFF_NOREADRAW)==0); - if (!isMapped(tif)) { - tmsize_t cc; - - if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip))) { - TIFFErrorExtR(tif, module, - "Seek error at scanline %"PRIu32", strip %"PRIu32, - tif->tif_row, strip); - return ((tmsize_t)(-1)); - } - cc = TIFFReadFile(tif, buf, size); - if (cc != size) { - TIFFErrorExtR(tif, module, - "Read error at scanline %"PRIu32"; got %"TIFF_SSIZE_FORMAT" bytes, expected %"TIFF_SSIZE_FORMAT, - tif->tif_row, - cc, - size); - return ((tmsize_t)(-1)); - } - } else { - tmsize_t ma = 0; - tmsize_t n; - if ((TIFFGetStrileOffset(tif, strip) > (uint64_t)TIFF_TMSIZE_T_MAX) || - ((ma=(tmsize_t)TIFFGetStrileOffset(tif, strip))>tif->tif_size)) - { - n=0; - } - else if( ma > TIFF_TMSIZE_T_MAX - size ) - { - n=0; - } - else - { - tmsize_t mb=ma+size; - if (mb>tif->tif_size) - n=tif->tif_size-ma; - else - n=size; - } - if (n!=size) { - TIFFErrorExtR(tif, module, - "Read error at scanline %"PRIu32", strip %"PRIu32"; got %"TIFF_SSIZE_FORMAT" bytes, expected %"TIFF_SSIZE_FORMAT, - tif->tif_row, - strip, - n, - size); - return ((tmsize_t)(-1)); - } - _TIFFmemcpy(buf, tif->tif_base + ma, - size); - } - return (size); + if ((*tif->tif_decodestrip)(tif, *buf, this_stripsize, plane) <= 0) + return ((tmsize_t)(-1)); + (*tif->tif_postdecode)(tif, *buf, this_stripsize); + return (this_stripsize); } -static tmsize_t -TIFFReadRawStripOrTile2(TIFF* tif, uint32_t strip_or_tile, int is_strip, - tmsize_t size, const char* module) +static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf, + tmsize_t size, const char *module) { - assert( !isMapped(tif) ); - assert((tif->tif_flags&TIFF_NOREADRAW)==0); + assert((tif->tif_flags & TIFF_NOREADRAW) == 0); + if (!isMapped(tif)) + { + tmsize_t cc; - if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile))) { - if( is_strip ) - { - TIFFErrorExtR(tif, module, - "Seek error at scanline %"PRIu32", strip %"PRIu32, - tif->tif_row, - strip_or_tile); - } + if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip))) + { + TIFFErrorExtR(tif, module, + "Seek error at scanline %" PRIu32 ", strip %" PRIu32, + tif->tif_row, strip); + return ((tmsize_t)(-1)); + } + cc = TIFFReadFile(tif, buf, size); + if (cc != size) + { + TIFFErrorExtR(tif, module, + "Read error at scanline %" PRIu32 + "; got %" TIFF_SSIZE_FORMAT + " bytes, expected %" TIFF_SSIZE_FORMAT, + tif->tif_row, cc, size); + return ((tmsize_t)(-1)); + } + } + else + { + tmsize_t ma = 0; + tmsize_t n; + if ((TIFFGetStrileOffset(tif, strip) > (uint64_t)TIFF_TMSIZE_T_MAX) || + ((ma = (tmsize_t)TIFFGetStrileOffset(tif, strip)) > tif->tif_size)) + { + n = 0; + } + else if (ma > TIFF_TMSIZE_T_MAX - size) + { + n = 0; + } + else + { + tmsize_t mb = ma + size; + if (mb > tif->tif_size) + n = tif->tif_size - ma; else - { - TIFFErrorExtR(tif, module, - "Seek error at row %"PRIu32", col %"PRIu32", tile %"PRIu32, - tif->tif_row, - tif->tif_col, - strip_or_tile); - } + n = size; + } + if (n != size) + { + TIFFErrorExtR(tif, module, + "Read error at scanline %" PRIu32 ", strip %" PRIu32 + "; got %" TIFF_SSIZE_FORMAT + " bytes, expected %" TIFF_SSIZE_FORMAT, + tif->tif_row, strip, n, size); return ((tmsize_t)(-1)); } + _TIFFmemcpy(buf, tif->tif_base + ma, size); + } + return (size); +} - if( !TIFFReadAndRealloc( tif, size, 0, is_strip, - strip_or_tile, module ) ) +static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile, + int is_strip, tmsize_t size, + const char *module) +{ + assert(!isMapped(tif)); + assert((tif->tif_flags & TIFF_NOREADRAW) == 0); + + if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile))) + { + if (is_strip) { - return ((tmsize_t)(-1)); + TIFFErrorExtR(tif, module, + "Seek error at scanline %" PRIu32 ", strip %" PRIu32, + tif->tif_row, strip_or_tile); } + else + { + TIFFErrorExtR(tif, module, + "Seek error at row %" PRIu32 ", col %" PRIu32 + ", tile %" PRIu32, + tif->tif_row, tif->tif_col, strip_or_tile); + } + return ((tmsize_t)(-1)); + } - return (size); + if (!TIFFReadAndRealloc(tif, size, 0, is_strip, strip_or_tile, module)) + { + return ((tmsize_t)(-1)); + } + + return (size); } /* * Read a strip of data from the file. */ -tmsize_t -TIFFReadRawStrip(TIFF* tif, uint32_t strip, void* buf, tmsize_t size) +tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf, tmsize_t size) { - static const char module[] = "TIFFReadRawStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t bytecount64; - tmsize_t bytecountm; - - if (!TIFFCheckRead(tif, 0)) - return ((tmsize_t)(-1)); - if (strip >= td->td_nstrips) { - TIFFErrorExtR(tif, module, - "%"PRIu32": Strip out of range, max %"PRIu32, - strip, - td->td_nstrips); - return ((tmsize_t)(-1)); - } - if (tif->tif_flags&TIFF_NOREADRAW) - { - TIFFErrorExtR(tif, module, - "Compression scheme does not support access to raw uncompressed data"); - return ((tmsize_t)(-1)); - } - bytecount64 = TIFFGetStrileByteCount(tif, strip); - if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64) - bytecountm = size; - else - bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); - if( bytecountm == 0 ) { - return ((tmsize_t)(-1)); - } - return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module)); + static const char module[] = "TIFFReadRawStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t bytecount64; + tmsize_t bytecountm; + + if (!TIFFCheckRead(tif, 0)) + return ((tmsize_t)(-1)); + if (strip >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, + "%" PRIu32 ": Strip out of range, max %" PRIu32, strip, + td->td_nstrips); + return ((tmsize_t)(-1)); + } + if (tif->tif_flags & TIFF_NOREADRAW) + { + TIFFErrorExtR(tif, module, + "Compression scheme does not support access to raw " + "uncompressed data"); + return ((tmsize_t)(-1)); + } + bytecount64 = TIFFGetStrileByteCount(tif, strip); + if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64) + bytecountm = size; + else + bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); + if (bytecountm == 0) + { + return ((tmsize_t)(-1)); + } + return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module)); } TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW -static uint64_t NoSanitizeSubUInt64(uint64_t a, uint64_t b) -{ - return a - b; -} +static uint64_t NoSanitizeSubUInt64(uint64_t a, uint64_t b) { return a - b; } /* * Read the specified strip and setup for decoding. The data buffer is * expanded, as necessary, to hold the strip's data. */ -int -TIFFFillStrip(TIFF* tif, uint32_t strip) +int TIFFFillStrip(TIFF *tif, uint32_t strip) { - static const char module[] = "TIFFFillStrip"; - TIFFDirectory *td = &tif->tif_dir; - - if ((tif->tif_flags&TIFF_NOREADRAW)==0) - { - uint64_t bytecount = TIFFGetStrileByteCount(tif, strip); - if( bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX ) { - TIFFErrorExtR(tif, module, - "Invalid strip byte count %"PRIu64", strip %"PRIu32, - bytecount, - strip); - return (0); - } - - /* To avoid excessive memory allocations: */ - /* Byte count should normally not be larger than a number of */ - /* times the uncompressed size plus some margin */ - if( bytecount > 1024 * 1024 ) + static const char module[] = "TIFFFillStrip"; + TIFFDirectory *td = &tif->tif_dir; + + if ((tif->tif_flags & TIFF_NOREADRAW) == 0) + { + uint64_t bytecount = TIFFGetStrileByteCount(tif, strip); + if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX) + { + TIFFErrorExtR(tif, module, + "Invalid strip byte count %" PRIu64 + ", strip %" PRIu32, + bytecount, strip); + return (0); + } + + /* To avoid excessive memory allocations: */ + /* Byte count should normally not be larger than a number of */ + /* times the uncompressed size plus some margin */ + if (bytecount > 1024 * 1024) + { + /* 10 and 4096 are just values that could be adjusted. */ + /* Hopefully they are safe enough for all codecs */ + tmsize_t stripsize = TIFFStripSize(tif); + if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize) + { + uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096; + TIFFErrorExtR(tif, module, + "Too large strip byte count %" PRIu64 + ", strip %" PRIu32 ". Limiting to %" PRIu64, + bytecount, strip, newbytecount); + bytecount = newbytecount; + } + } + + if (isMapped(tif)) + { + /* + * We must check for overflow, potentially causing + * an OOB read. Instead of simple + * + * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size + * + * comparison (which can overflow) we do the following + * two comparisons: + */ + if (bytecount > (uint64_t)tif->tif_size || + TIFFGetStrileOffset(tif, strip) > + (uint64_t)tif->tif_size - bytecount) + { + /* + * This error message might seem strange, but + * it's what would happen if a read were done + * instead. + */ + TIFFErrorExtR( + tif, module, + + "Read error on strip %" PRIu32 "; " + "got %" PRIu64 " bytes, expected %" PRIu64, + strip, + NoSanitizeSubUInt64(tif->tif_size, + TIFFGetStrileOffset(tif, strip)), + bytecount); + tif->tif_curstrip = NOSTRIP; + return (0); + } + } + + if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) || + (tif->tif_flags & TIFF_NOBITREV))) + { + /* + * The image is mapped into memory and we either don't + * need to flip bits or the compression routine is + * going to handle this operation itself. In this + * case, avoid copying the raw data and instead just + * reference the data from the memory mapped file + * image. This assumes that the decompression + * routines do not modify the contents of the raw data + * buffer (if they try to, the application will get a + * fault since the file is mapped read-only). + */ + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + { + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + tif->tif_flags &= ~TIFF_MYBUFFER; + tif->tif_rawdatasize = (tmsize_t)bytecount; + tif->tif_rawdata = + tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip); + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = (tmsize_t)bytecount; + + /* + * When we have tif_rawdata reference directly into the memory + * mapped file we need to be pretty careful about how we use the + * rawdata. It is not a general purpose working buffer as it + * normally otherwise is. So we keep track of this fact to avoid + * using it improperly. + */ + tif->tif_flags |= TIFF_BUFFERMMAP; + } + else + { + /* + * Expand raw data buffer, if needed, to hold data + * strip coming from file (perhaps should set upper + * bound on the size of a buffer we'll use?). + */ + tmsize_t bytecountm; + bytecountm = (tmsize_t)bytecount; + if ((uint64_t)bytecountm != bytecount) + { + TIFFErrorExtR(tif, module, "Integer overflow"); + return (0); + } + if (bytecountm > tif->tif_rawdatasize) + { + tif->tif_curstrip = NOSTRIP; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) + { + TIFFErrorExtR( + tif, module, + "Data buffer too small to hold strip %" PRIu32, strip); + return (0); + } + } + if (tif->tif_flags & TIFF_BUFFERMMAP) + { + tif->tif_curstrip = NOSTRIP; + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + tif->tif_flags &= ~TIFF_BUFFERMMAP; + } + + if (isMapped(tif)) + { + if (bytecountm > tif->tif_rawdatasize && + !TIFFReadBufferSetup(tif, 0, bytecountm)) + { + return (0); + } + if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, bytecountm, + module) != bytecountm) { - /* 10 and 4096 are just values that could be adjusted. */ - /* Hopefully they are safe enough for all codecs */ - tmsize_t stripsize = TIFFStripSize(tif); - if( stripsize != 0 && - (bytecount - 4096) / 10 > (uint64_t)stripsize ) - { - uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096; - TIFFErrorExtR(tif, module, - "Too large strip byte count %"PRIu64", strip %"PRIu32". Limiting to %"PRIu64, - bytecount, - strip, - newbytecount); - bytecount = newbytecount; - } - } - - if (isMapped(tif)) { - /* - * We must check for overflow, potentially causing - * an OOB read. Instead of simple - * - * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size - * - * comparison (which can overflow) we do the following - * two comparisons: - */ - if (bytecount > (uint64_t)tif->tif_size || - TIFFGetStrileOffset(tif, strip) > (uint64_t)tif->tif_size - bytecount) { - /* - * This error message might seem strange, but - * it's what would happen if a read were done - * instead. - */ - TIFFErrorExtR(tif, module, - - "Read error on strip %"PRIu32"; " - "got %"PRIu64" bytes, expected %"PRIu64, - strip, - NoSanitizeSubUInt64(tif->tif_size, TIFFGetStrileOffset(tif, strip)), - bytecount); - tif->tif_curstrip = NOSTRIP; - return (0); - } - } - - if (isMapped(tif) && - (isFillOrder(tif, td->td_fillorder) - || (tif->tif_flags & TIFF_NOBITREV))) { - /* - * The image is mapped into memory and we either don't - * need to flip bits or the compression routine is - * going to handle this operation itself. In this - * case, avoid copying the raw data and instead just - * reference the data from the memory mapped file - * image. This assumes that the decompression - * routines do not modify the contents of the raw data - * buffer (if they try to, the application will get a - * fault since the file is mapped read-only). - */ - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - } - tif->tif_flags &= ~TIFF_MYBUFFER; - tif->tif_rawdatasize = (tmsize_t)bytecount; - tif->tif_rawdata = tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip); - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = (tmsize_t) bytecount; - - /* - * When we have tif_rawdata reference directly into the memory mapped file - * we need to be pretty careful about how we use the rawdata. It is not - * a general purpose working buffer as it normally otherwise is. So we - * keep track of this fact to avoid using it improperly. - */ - tif->tif_flags |= TIFF_BUFFERMMAP; - } else { - /* - * Expand raw data buffer, if needed, to hold data - * strip coming from file (perhaps should set upper - * bound on the size of a buffer we'll use?). - */ - tmsize_t bytecountm; - bytecountm=(tmsize_t)bytecount; - if ((uint64_t)bytecountm != bytecount) - { - TIFFErrorExtR(tif,module,"Integer overflow"); - return(0); - } - if (bytecountm > tif->tif_rawdatasize) { - tif->tif_curstrip = NOSTRIP; - if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - TIFFErrorExtR(tif, module, - "Data buffer too small to hold strip %"PRIu32, - strip); - return (0); - } - } - if (tif->tif_flags&TIFF_BUFFERMMAP) { - tif->tif_curstrip = NOSTRIP; - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - tif->tif_flags &= ~TIFF_BUFFERMMAP; - } - - if( isMapped(tif) ) - { - if (bytecountm > tif->tif_rawdatasize && - !TIFFReadBufferSetup(tif, 0, bytecountm)) - { - return (0); - } - if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, - bytecountm, module) != bytecountm) - { - return (0); - } - } - else - { - if (TIFFReadRawStripOrTile2(tif, strip, 1, - bytecountm, module) != bytecountm) - { - return (0); - } - } - - - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = bytecountm; - - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, bytecountm); + return (0); } - } - return (TIFFStartStrip(tif, strip)); + } + else + { + if (TIFFReadRawStripOrTile2(tif, strip, 1, bytecountm, + module) != bytecountm) + { + return (0); + } + } + + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = bytecountm; + + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, bytecountm); + } + } + return (TIFFStartStrip(tif, strip)); } /* @@ -893,160 +913,162 @@ TIFFFillStrip(TIFF* tif, uint32_t strip) * Read and decompress a tile of data. The * tile is selected by the (x,y,z,s) coordinates. */ -tmsize_t -TIFFReadTile(TIFF* tif, void* buf, uint32_t x, uint32_t y, uint32_t z, uint16_t s) +tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z, + uint16_t s) { - if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) - return ((tmsize_t)(-1)); - return (TIFFReadEncodedTile(tif, - TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); + if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) + return ((tmsize_t)(-1)); + return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf, + (tmsize_t)(-1))); } /* * Read a tile of data and decompress the specified * amount into the user-supplied buffer. */ -tmsize_t -TIFFReadEncodedTile(TIFF* tif, uint32_t tile, void* buf, tmsize_t size) +tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size) { - static const char module[] = "TIFFReadEncodedTile"; - TIFFDirectory *td = &tif->tif_dir; - tmsize_t tilesize = tif->tif_tilesize; - - if (!TIFFCheckRead(tif, 1)) - return ((tmsize_t)(-1)); - if (tile >= td->td_nstrips) { - TIFFErrorExtR(tif, module, - "%"PRIu32": Tile out of range, max %"PRIu32, - tile, td->td_nstrips); - return ((tmsize_t)(-1)); - } + static const char module[] = "TIFFReadEncodedTile"; + TIFFDirectory *td = &tif->tif_dir; + tmsize_t tilesize = tif->tif_tilesize; + + if (!TIFFCheckRead(tif, 1)) + return ((tmsize_t)(-1)); + if (tile >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, + "%" PRIu32 ": Tile out of range, max %" PRIu32, tile, + td->td_nstrips); + return ((tmsize_t)(-1)); + } /* shortcut to avoid an extra memcpy() */ - if( td->td_compression == COMPRESSION_NONE && - size!=(tmsize_t)(-1) && size >= tilesize && - !isMapped(tif) && - ((tif->tif_flags&TIFF_NOREADRAW)==0) ) + if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) && + size >= tilesize && !isMapped(tif) && + ((tif->tif_flags & TIFF_NOREADRAW) == 0)) { if (TIFFReadRawTile1(tif, tile, buf, tilesize, module) != tilesize) return ((tmsize_t)(-1)); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(buf,tilesize); + TIFFReverseBits(buf, tilesize); - (*tif->tif_postdecode)(tif,buf,tilesize); + (*tif->tif_postdecode)(tif, buf, tilesize); return (tilesize); } - if (size == (tmsize_t)(-1)) - size = tilesize; - else if (size > tilesize) - size = tilesize; - if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif, - (uint8_t*) buf, size, (uint16_t)(tile / td->td_stripsperimage))) { - (*tif->tif_postdecode)(tif, (uint8_t*) buf, size); - return (size); - } else - return ((tmsize_t)(-1)); + if (size == (tmsize_t)(-1)) + size = tilesize; + else if (size > tilesize) + size = tilesize; + if (TIFFFillTile(tif, tile) && + (*tif->tif_decodetile)(tif, (uint8_t *)buf, size, + (uint16_t)(tile / td->td_stripsperimage))) + { + (*tif->tif_postdecode)(tif, (uint8_t *)buf, size); + return (size); + } + else + return ((tmsize_t)(-1)); } -/* Variant of TIFFReadTile() that does - * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after TIFFFillTile() has - * succeeded. This avoid excessive memory allocation in case of truncated - * file. +/* Variant of TIFFReadTile() that does + * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after + * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case + * of truncated file. * * calls regular TIFFReadEncodedTile() if *buf != NULL */ -tmsize_t -_TIFFReadTileAndAllocBuffer(TIFF* tif, - void **buf, tmsize_t bufsizetoalloc, - uint32_t x, uint32_t y, uint32_t z, uint16_t s) +tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf, + tmsize_t bufsizetoalloc, uint32_t x, + uint32_t y, uint32_t z, uint16_t s) { if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) - return ((tmsize_t)(-1)); - return (_TIFFReadEncodedTileAndAllocBuffer(tif, - TIFFComputeTile(tif, x, y, z, s), - buf, bufsizetoalloc, - (tmsize_t)(-1))); + return ((tmsize_t)(-1)); + return (_TIFFReadEncodedTileAndAllocBuffer( + tif, TIFFComputeTile(tif, x, y, z, s), buf, bufsizetoalloc, + (tmsize_t)(-1))); } -/* Variant of TIFFReadEncodedTile() that does - * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after TIFFFillTile() has - * succeeded. This avoid excessive memory allocation in case of truncated - * file. +/* Variant of TIFFReadEncodedTile() that does + * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after + * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case + * of truncated file. * * calls regular TIFFReadEncodedTile() if *buf != NULL */ -tmsize_t -_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32_t tile, - void **buf, tmsize_t bufsizetoalloc, - tmsize_t size_to_read) +tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile, + void **buf, tmsize_t bufsizetoalloc, + tmsize_t size_to_read) { static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer"; TIFFDirectory *td = &tif->tif_dir; tmsize_t tilesize = tif->tif_tilesize; - if( *buf != NULL ) + if (*buf != NULL) { return TIFFReadEncodedTile(tif, tile, *buf, size_to_read); } if (!TIFFCheckRead(tif, 1)) - return ((tmsize_t)(-1)); - if (tile >= td->td_nstrips) { - TIFFErrorExtR(tif, module, - "%"PRIu32": Tile out of range, max %"PRIu32, - tile, td->td_nstrips); - return ((tmsize_t)(-1)); + return ((tmsize_t)(-1)); + if (tile >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, + "%" PRIu32 ": Tile out of range, max %" PRIu32, tile, + td->td_nstrips); + return ((tmsize_t)(-1)); } - if (!TIFFFillTile(tif,tile)) - return((tmsize_t)(-1)); + if (!TIFFFillTile(tif, tile)) + return ((tmsize_t)(-1)); /* Sanity checks to avoid excessive memory allocation */ /* Cf https://gitlab.com/libtiff/libtiff/-/issues/479 */ - if (td->td_compression == COMPRESSION_NONE) { - if (tif->tif_rawdatasize != tilesize) { + if (td->td_compression == COMPRESSION_NONE) + { + if (tif->tif_rawdatasize != tilesize) + { TIFFErrorExtR(tif, TIFFFileName(tif), - "Invalid tile byte count for tile %u. " - "Expected %"PRIu64", got %"PRIu64, - tile, - (uint64_t)tilesize, + "Invalid tile byte count for tile %u. " + "Expected %" PRIu64 ", got %" PRIu64, + tile, (uint64_t)tilesize, (uint64_t)tif->tif_rawdatasize); - return((tmsize_t)(-1)); + return ((tmsize_t)(-1)); } } - else { + else + { /* Max compression ratio experimentally determined. Might be fragile... * Only apply this heuristics to situations where the memory allocation * would be big, to avoid breaking nominal use cases. */ const int maxCompressionRatio = - td->td_compression == COMPRESSION_ZSTD ? - 33000 : - td->td_compression == COMPRESSION_JXL ? + td->td_compression == COMPRESSION_ZSTD ? 33000 + : td->td_compression == COMPRESSION_JXL + ? /* Evaluated on a 8000x8000 tile */ - 25000 * (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1) : - td->td_compression == COMPRESSION_LZMA ? - 7000 : - 1000; - if (bufsizetoalloc > 100 * 1000 * 1000 && - tif->tif_rawdatasize < tilesize / maxCompressionRatio) { + 25000 * (td->td_planarconfig == PLANARCONFIG_CONTIG + ? td->td_samplesperpixel + : 1) + : td->td_compression == COMPRESSION_LZMA ? 7000 : 1000; + if (bufsizetoalloc > 100 * 1000 * 1000 && + tif->tif_rawdatasize < tilesize / maxCompressionRatio) + { TIFFErrorExtR(tif, TIFFFileName(tif), - "Likely invalid tile byte count for tile %u. " - "Uncompressed tile size is %"PRIu64", " - "compressed one is %"PRIu64, - tile, - (uint64_t)tilesize, + "Likely invalid tile byte count for tile %u. " + "Uncompressed tile size is %" PRIu64 ", " + "compressed one is %" PRIu64, + tile, (uint64_t)tilesize, (uint64_t)tif->tif_rawdatasize); - return((tmsize_t)(-1)); + return ((tmsize_t)(-1)); } } *buf = _TIFFmallocExt(tif, bufsizetoalloc); - if (*buf == NULL) { - TIFFErrorExtR(tif, TIFFFileName(tif), - "No space for tile buffer"); - return((tmsize_t)(-1)); + if (*buf == NULL) + { + TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer"); + return ((tmsize_t)(-1)); } _TIFFmemset(*buf, 0, bufsizetoalloc); @@ -1054,250 +1076,261 @@ _TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32_t tile, size_to_read = tilesize; else if (size_to_read > tilesize) size_to_read = tilesize; - if( (*tif->tif_decodetile)(tif, - (uint8_t*) *buf, size_to_read, (uint16_t)(tile / td->td_stripsperimage))) { - (*tif->tif_postdecode)(tif, (uint8_t*) *buf, size_to_read); + if ((*tif->tif_decodetile)(tif, (uint8_t *)*buf, size_to_read, + (uint16_t)(tile / td->td_stripsperimage))) + { + (*tif->tif_postdecode)(tif, (uint8_t *)*buf, size_to_read); return (size_to_read); - } else + } + else return ((tmsize_t)(-1)); } -static tmsize_t -TIFFReadRawTile1(TIFF* tif, uint32_t tile, void* buf, tmsize_t size, const char* module) +static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf, + tmsize_t size, const char *module) { - assert((tif->tif_flags&TIFF_NOREADRAW)==0); - if (!isMapped(tif)) { - tmsize_t cc; - - if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile))) { - TIFFErrorExtR(tif, module, - "Seek error at row %"PRIu32", col %"PRIu32", tile %"PRIu32, - tif->tif_row, - tif->tif_col, - tile); - return ((tmsize_t)(-1)); - } - cc = TIFFReadFile(tif, buf, size); - if (cc != size) { - TIFFErrorExtR(tif, module, - "Read error at row %"PRIu32", col %"PRIu32"; got %"TIFF_SSIZE_FORMAT" bytes, expected %"TIFF_SSIZE_FORMAT, - tif->tif_row, - tif->tif_col, - cc, - size); - return ((tmsize_t)(-1)); - } - } else { - tmsize_t ma,mb; - tmsize_t n; - ma=(tmsize_t)TIFFGetStrileOffset(tif, tile); - mb=ma+size; - if ((TIFFGetStrileOffset(tif, tile) > (uint64_t)TIFF_TMSIZE_T_MAX) || (ma > tif->tif_size)) - n=0; - else if ((mb<ma)||(mb<size)||(mb>tif->tif_size)) - n=tif->tif_size-ma; - else - n=size; - if (n!=size) { - TIFFErrorExtR(tif, module, -"Read error at row %"PRIu32", col %"PRIu32", tile %"PRIu32"; got %"TIFF_SSIZE_FORMAT" bytes, expected %"TIFF_SSIZE_FORMAT, - tif->tif_row, - tif->tif_col, - tile, - n, - size); - return ((tmsize_t)(-1)); - } - _TIFFmemcpy(buf, tif->tif_base + ma, size); - } - return (size); + assert((tif->tif_flags & TIFF_NOREADRAW) == 0); + if (!isMapped(tif)) + { + tmsize_t cc; + + if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile))) + { + TIFFErrorExtR(tif, module, + "Seek error at row %" PRIu32 ", col %" PRIu32 + ", tile %" PRIu32, + tif->tif_row, tif->tif_col, tile); + return ((tmsize_t)(-1)); + } + cc = TIFFReadFile(tif, buf, size); + if (cc != size) + { + TIFFErrorExtR(tif, module, + "Read error at row %" PRIu32 ", col %" PRIu32 + "; got %" TIFF_SSIZE_FORMAT + " bytes, expected %" TIFF_SSIZE_FORMAT, + tif->tif_row, tif->tif_col, cc, size); + return ((tmsize_t)(-1)); + } + } + else + { + tmsize_t ma, mb; + tmsize_t n; + ma = (tmsize_t)TIFFGetStrileOffset(tif, tile); + mb = ma + size; + if ((TIFFGetStrileOffset(tif, tile) > (uint64_t)TIFF_TMSIZE_T_MAX) || + (ma > tif->tif_size)) + n = 0; + else if ((mb < ma) || (mb < size) || (mb > tif->tif_size)) + n = tif->tif_size - ma; + else + n = size; + if (n != size) + { + TIFFErrorExtR(tif, module, + "Read error at row %" PRIu32 ", col %" PRIu32 + ", tile %" PRIu32 "; got %" TIFF_SSIZE_FORMAT + " bytes, expected %" TIFF_SSIZE_FORMAT, + tif->tif_row, tif->tif_col, tile, n, size); + return ((tmsize_t)(-1)); + } + _TIFFmemcpy(buf, tif->tif_base + ma, size); + } + return (size); } /* * Read a tile of data from the file. */ -tmsize_t -TIFFReadRawTile(TIFF* tif, uint32_t tile, void* buf, tmsize_t size) +tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size) { - static const char module[] = "TIFFReadRawTile"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t bytecount64; - tmsize_t bytecountm; - - if (!TIFFCheckRead(tif, 1)) - return ((tmsize_t)(-1)); - if (tile >= td->td_nstrips) { - TIFFErrorExtR(tif, module, - "%"PRIu32": Tile out of range, max %"PRIu32, - tile, td->td_nstrips); - return ((tmsize_t)(-1)); - } - if (tif->tif_flags&TIFF_NOREADRAW) - { - TIFFErrorExtR(tif, module, - "Compression scheme does not support access to raw uncompressed data"); - return ((tmsize_t)(-1)); - } - bytecount64 = TIFFGetStrileByteCount(tif, tile); - if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64) - bytecountm = size; - else - bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); - if( bytecountm == 0 ) { - return ((tmsize_t)(-1)); - } - return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module)); + static const char module[] = "TIFFReadRawTile"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t bytecount64; + tmsize_t bytecountm; + + if (!TIFFCheckRead(tif, 1)) + return ((tmsize_t)(-1)); + if (tile >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, + "%" PRIu32 ": Tile out of range, max %" PRIu32, tile, + td->td_nstrips); + return ((tmsize_t)(-1)); + } + if (tif->tif_flags & TIFF_NOREADRAW) + { + TIFFErrorExtR(tif, module, + "Compression scheme does not support access to raw " + "uncompressed data"); + return ((tmsize_t)(-1)); + } + bytecount64 = TIFFGetStrileByteCount(tif, tile); + if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64) + bytecountm = size; + else + bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module); + if (bytecountm == 0) + { + return ((tmsize_t)(-1)); + } + return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module)); } /* * Read the specified tile and setup for decoding. The data buffer is * expanded, as necessary, to hold the tile's data. */ -int -TIFFFillTile(TIFF* tif, uint32_t tile) +int TIFFFillTile(TIFF *tif, uint32_t tile) { - static const char module[] = "TIFFFillTile"; - TIFFDirectory *td = &tif->tif_dir; - - if ((tif->tif_flags&TIFF_NOREADRAW)==0) - { - uint64_t bytecount = TIFFGetStrileByteCount(tif, tile); - if( bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX ) { - TIFFErrorExtR(tif, module, - "%"PRIu64": Invalid tile byte count, tile %"PRIu32, - bytecount, - tile); - return (0); - } - - /* To avoid excessive memory allocations: */ - /* Byte count should normally not be larger than a number of */ - /* times the uncompressed size plus some margin */ - if( bytecount > 1024 * 1024 ) + static const char module[] = "TIFFFillTile"; + TIFFDirectory *td = &tif->tif_dir; + + if ((tif->tif_flags & TIFF_NOREADRAW) == 0) + { + uint64_t bytecount = TIFFGetStrileByteCount(tif, tile); + if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX) + { + TIFFErrorExtR(tif, module, + "%" PRIu64 ": Invalid tile byte count, tile %" PRIu32, + bytecount, tile); + return (0); + } + + /* To avoid excessive memory allocations: */ + /* Byte count should normally not be larger than a number of */ + /* times the uncompressed size plus some margin */ + if (bytecount > 1024 * 1024) + { + /* 10 and 4096 are just values that could be adjusted. */ + /* Hopefully they are safe enough for all codecs */ + tmsize_t stripsize = TIFFTileSize(tif); + if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize) + { + uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096; + TIFFErrorExtR(tif, module, + "Too large tile byte count %" PRIu64 + ", tile %" PRIu32 ". Limiting to %" PRIu64, + bytecount, tile, newbytecount); + bytecount = newbytecount; + } + } + + if (isMapped(tif)) + { + /* + * We must check for overflow, potentially causing + * an OOB read. Instead of simple + * + * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size + * + * comparison (which can overflow) we do the following + * two comparisons: + */ + if (bytecount > (uint64_t)tif->tif_size || + TIFFGetStrileOffset(tif, tile) > + (uint64_t)tif->tif_size - bytecount) + { + tif->tif_curtile = NOTILE; + return (0); + } + } + + if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) || + (tif->tif_flags & TIFF_NOBITREV))) + { + /* + * The image is mapped into memory and we either don't + * need to flip bits or the compression routine is + * going to handle this operation itself. In this + * case, avoid copying the raw data and instead just + * reference the data from the memory mapped file + * image. This assumes that the decompression + * routines do not modify the contents of the raw data + * buffer (if they try to, the application will get a + * fault since the file is mapped read-only). + */ + if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) + { + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + tif->tif_flags &= ~TIFF_MYBUFFER; + + tif->tif_rawdatasize = (tmsize_t)bytecount; + tif->tif_rawdata = + tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile); + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = (tmsize_t)bytecount; + tif->tif_flags |= TIFF_BUFFERMMAP; + } + else + { + /* + * Expand raw data buffer, if needed, to hold data + * tile coming from file (perhaps should set upper + * bound on the size of a buffer we'll use?). + */ + tmsize_t bytecountm; + bytecountm = (tmsize_t)bytecount; + if ((uint64_t)bytecountm != bytecount) + { + TIFFErrorExtR(tif, module, "Integer overflow"); + return (0); + } + if (bytecountm > tif->tif_rawdatasize) + { + tif->tif_curtile = NOTILE; + if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - /* 10 and 4096 are just values that could be adjusted. */ - /* Hopefully they are safe enough for all codecs */ - tmsize_t stripsize = TIFFTileSize(tif); - if( stripsize != 0 && - (bytecount - 4096) / 10 > (uint64_t)stripsize ) - { - uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096; - TIFFErrorExtR(tif, module, - "Too large tile byte count %"PRIu64", tile %"PRIu32". Limiting to %"PRIu64, - bytecount, - tile, - newbytecount); - bytecount = newbytecount; - } - } - - if (isMapped(tif)) { - /* - * We must check for overflow, potentially causing - * an OOB read. Instead of simple - * - * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size - * - * comparison (which can overflow) we do the following - * two comparisons: - */ - if (bytecount > (uint64_t)tif->tif_size || - TIFFGetStrileOffset(tif, tile) > (uint64_t)tif->tif_size - bytecount) { - tif->tif_curtile = NOTILE; - return (0); - } - } - - if (isMapped(tif) && - (isFillOrder(tif, td->td_fillorder) - || (tif->tif_flags & TIFF_NOBITREV))) { - /* - * The image is mapped into memory and we either don't - * need to flip bits or the compression routine is - * going to handle this operation itself. In this - * case, avoid copying the raw data and instead just - * reference the data from the memory mapped file - * image. This assumes that the decompression - * routines do not modify the contents of the raw data - * buffer (if they try to, the application will get a - * fault since the file is mapped read-only). - */ - if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - } - tif->tif_flags &= ~TIFF_MYBUFFER; - - tif->tif_rawdatasize = (tmsize_t)bytecount; - tif->tif_rawdata = - tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile); - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = (tmsize_t) bytecount; - tif->tif_flags |= TIFF_BUFFERMMAP; - } else { - /* - * Expand raw data buffer, if needed, to hold data - * tile coming from file (perhaps should set upper - * bound on the size of a buffer we'll use?). - */ - tmsize_t bytecountm; - bytecountm=(tmsize_t)bytecount; - if ((uint64_t)bytecountm != bytecount) - { - TIFFErrorExtR(tif,module,"Integer overflow"); - return(0); - } - if (bytecountm > tif->tif_rawdatasize) { - tif->tif_curtile = NOTILE; - if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { - TIFFErrorExtR(tif, module, - "Data buffer too small to hold tile %"PRIu32, - tile); - return (0); - } - } - if (tif->tif_flags&TIFF_BUFFERMMAP) { - tif->tif_curtile = NOTILE; - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - tif->tif_flags &= ~TIFF_BUFFERMMAP; - } - - if( isMapped(tif) ) - { - if (bytecountm > tif->tif_rawdatasize && - !TIFFReadBufferSetup(tif, 0, bytecountm)) - { - return (0); - } - if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, - bytecountm, module) != bytecountm) - { - return (0); - } - } - else - { - if (TIFFReadRawStripOrTile2(tif, tile, 0, - bytecountm, module) != bytecountm) - { - return (0); - } - } - - - tif->tif_rawdataoff = 0; - tif->tif_rawdataloaded = bytecountm; - - if (tif->tif_rawdata != NULL && - !isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, - tif->tif_rawdataloaded); - } - } - return (TIFFStartTile(tif, tile)); + TIFFErrorExtR(tif, module, + "Data buffer too small to hold tile %" PRIu32, + tile); + return (0); + } + } + if (tif->tif_flags & TIFF_BUFFERMMAP) + { + tif->tif_curtile = NOTILE; + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + tif->tif_flags &= ~TIFF_BUFFERMMAP; + } + + if (isMapped(tif)) + { + if (bytecountm > tif->tif_rawdatasize && + !TIFFReadBufferSetup(tif, 0, bytecountm)) + { + return (0); + } + if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, bytecountm, + module) != bytecountm) + { + return (0); + } + } + else + { + if (TIFFReadRawStripOrTile2(tif, tile, 0, bytecountm, module) != + bytecountm) + { + return (0); + } + } + + tif->tif_rawdataoff = 0; + tif->tif_rawdataloaded = bytecountm; + + if (tif->tif_rawdata != NULL && + !isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdataloaded); + } + } + return (TIFFStartTile(tif, tile)); } /* @@ -1309,180 +1342,191 @@ TIFFFillTile(TIFF* tif, uint32_t tile) * large enough to hold any individual strip of * raw data. */ -int -TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size) +int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size) { - static const char module[] = "TIFFReadBufferSetup"; - - assert((tif->tif_flags&TIFF_NOREADRAW)==0); - tif->tif_flags &= ~TIFF_BUFFERMMAP; - - if (tif->tif_rawdata) { - if (tif->tif_flags & TIFF_MYBUFFER) - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_rawdata = NULL; - tif->tif_rawdatasize = 0; - } - if (bp) { - tif->tif_rawdatasize = size; - tif->tif_rawdata = (uint8_t*) bp; - tif->tif_flags &= ~TIFF_MYBUFFER; - } else { - tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64_t)size, 1024); - if (tif->tif_rawdatasize==0) { - TIFFErrorExtR(tif, module, - "Invalid buffer size"); - return (0); - } - /* Initialize to zero to avoid uninitialized buffers in case of */ - /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */ - tif->tif_rawdata = (uint8_t*) _TIFFcallocExt(tif, 1, tif->tif_rawdatasize); - tif->tif_flags |= TIFF_MYBUFFER; - } - if (tif->tif_rawdata == NULL) { - TIFFErrorExtR(tif, module, - "No space for data buffer at scanline %"PRIu32, - tif->tif_row); - tif->tif_rawdatasize = 0; - return (0); - } - return (1); + static const char module[] = "TIFFReadBufferSetup"; + + assert((tif->tif_flags & TIFF_NOREADRAW) == 0); + tif->tif_flags &= ~TIFF_BUFFERMMAP; + + if (tif->tif_rawdata) + { + if (tif->tif_flags & TIFF_MYBUFFER) + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_rawdata = NULL; + tif->tif_rawdatasize = 0; + } + if (bp) + { + tif->tif_rawdatasize = size; + tif->tif_rawdata = (uint8_t *)bp; + tif->tif_flags &= ~TIFF_MYBUFFER; + } + else + { + tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64_t)size, 1024); + if (tif->tif_rawdatasize == 0) + { + TIFFErrorExtR(tif, module, "Invalid buffer size"); + return (0); + } + /* Initialize to zero to avoid uninitialized buffers in case of */ + /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */ + tif->tif_rawdata = + (uint8_t *)_TIFFcallocExt(tif, 1, tif->tif_rawdatasize); + tif->tif_flags |= TIFF_MYBUFFER; + } + if (tif->tif_rawdata == NULL) + { + TIFFErrorExtR(tif, module, + "No space for data buffer at scanline %" PRIu32, + tif->tif_row); + tif->tif_rawdatasize = 0; + return (0); + } + return (1); } /* * Set state to appear as if a * strip has just been read in. */ -static int -TIFFStartStrip(TIFF* tif, uint32_t strip) +static int TIFFStartStrip(TIFF *tif, uint32_t strip) { - TIFFDirectory *td = &tif->tif_dir; - - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { - if (!(*tif->tif_setupdecode)(tif)) - return (0); - tif->tif_flags |= TIFF_CODERSETUP; - } - tif->tif_curstrip = strip; - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; - tif->tif_flags &= ~TIFF_BUF4WRITE; - - if (tif->tif_flags&TIFF_NOREADRAW) - { - tif->tif_rawcp = NULL; - tif->tif_rawcc = 0; - } - else - { - tif->tif_rawcp = tif->tif_rawdata; - if( tif->tif_rawdataloaded > 0 ) - tif->tif_rawcc = tif->tif_rawdataloaded; - else - tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip); - } - if ((*tif->tif_predecode)(tif, - (uint16_t)(strip / td->td_stripsperimage)) == 0 ) { - /* Needed for example for scanline access, if tif_predecode */ - /* fails, and we try to read the same strip again. Without invalidating */ - /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */ - /* codec state. */ - tif->tif_curstrip = NOSTRIP; - return 0; - } - return 1; + TIFFDirectory *td = &tif->tif_dir; + + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) + { + if (!(*tif->tif_setupdecode)(tif)) + return (0); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_curstrip = strip; + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + tif->tif_flags &= ~TIFF_BUF4WRITE; + + if (tif->tif_flags & TIFF_NOREADRAW) + { + tif->tif_rawcp = NULL; + tif->tif_rawcc = 0; + } + else + { + tif->tif_rawcp = tif->tif_rawdata; + if (tif->tif_rawdataloaded > 0) + tif->tif_rawcc = tif->tif_rawdataloaded; + else + tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip); + } + if ((*tif->tif_predecode)(tif, (uint16_t)(strip / td->td_stripsperimage)) == + 0) + { + /* Needed for example for scanline access, if tif_predecode */ + /* fails, and we try to read the same strip again. Without invalidating + */ + /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */ + /* codec state. */ + tif->tif_curstrip = NOSTRIP; + return 0; + } + return 1; } /* * Set state to appear as if a * tile has just been read in. */ -static int -TIFFStartTile(TIFF* tif, uint32_t tile) +static int TIFFStartTile(TIFF *tif, uint32_t tile) { - static const char module[] = "TIFFStartTile"; - TIFFDirectory *td = &tif->tif_dir; - uint32_t howmany32; - - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { - if (!(*tif->tif_setupdecode)(tif)) - return (0); - tif->tif_flags |= TIFF_CODERSETUP; - } - tif->tif_curtile = tile; - howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); - if (howmany32 == 0) { - TIFFErrorExtR(tif,module,"Zero tiles"); - return 0; - } - tif->tif_row = (tile % howmany32) * td->td_tilelength; - howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength); - if (howmany32 == 0) { - TIFFErrorExtR(tif,module,"Zero tiles"); - return 0; - } - tif->tif_col = (tile % howmany32) * td->td_tilewidth; - tif->tif_flags &= ~TIFF_BUF4WRITE; - if (tif->tif_flags&TIFF_NOREADRAW) - { - tif->tif_rawcp = NULL; - tif->tif_rawcc = 0; - } - else - { - tif->tif_rawcp = tif->tif_rawdata; - if( tif->tif_rawdataloaded > 0 ) - tif->tif_rawcc = tif->tif_rawdataloaded; - else - tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile); - } - return ((*tif->tif_predecode)(tif, - (uint16_t)(tile / td->td_stripsperimage))); + static const char module[] = "TIFFStartTile"; + TIFFDirectory *td = &tif->tif_dir; + uint32_t howmany32; + + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) + { + if (!(*tif->tif_setupdecode)(tif)) + return (0); + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_curtile = tile; + howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); + if (howmany32 == 0) + { + TIFFErrorExtR(tif, module, "Zero tiles"); + return 0; + } + tif->tif_row = (tile % howmany32) * td->td_tilelength; + howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength); + if (howmany32 == 0) + { + TIFFErrorExtR(tif, module, "Zero tiles"); + return 0; + } + tif->tif_col = (tile % howmany32) * td->td_tilewidth; + tif->tif_flags &= ~TIFF_BUF4WRITE; + if (tif->tif_flags & TIFF_NOREADRAW) + { + tif->tif_rawcp = NULL; + tif->tif_rawcc = 0; + } + else + { + tif->tif_rawcp = tif->tif_rawdata; + if (tif->tif_rawdataloaded > 0) + tif->tif_rawcc = tif->tif_rawdataloaded; + else + tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile); + } + return ( + (*tif->tif_predecode)(tif, (uint16_t)(tile / td->td_stripsperimage))); } -static int -TIFFCheckRead(TIFF* tif, int tiles) +static int TIFFCheckRead(TIFF *tif, int tiles) { - if (tif->tif_mode == O_WRONLY) { - TIFFErrorExtR(tif, tif->tif_name, "File not open for reading"); - return (0); - } - if (tiles ^ isTiled(tif)) { - TIFFErrorExtR(tif, tif->tif_name, tiles ? - "Can not read tiles from a striped image" : - "Can not read scanlines from a tiled image"); - return (0); - } - return (1); + if (tif->tif_mode == O_WRONLY) + { + TIFFErrorExtR(tif, tif->tif_name, "File not open for reading"); + return (0); + } + if (tiles ^ isTiled(tif)) + { + TIFFErrorExtR(tif, tif->tif_name, + tiles ? "Can not read tiles from a striped image" + : "Can not read scanlines from a tiled image"); + return (0); + } + return (1); } /* Use the provided input buffer (inbuf, insize) and decompress it into * (outbuf, outsize). - * This function replaces the use of TIFFReadEncodedStrip()/TIFFReadEncodedTile() - * when the user can provide the buffer for the input data, for example when - * he wants to avoid libtiff to read the strile offset/count values from the - * [Strip|Tile][Offsets/ByteCounts] array. - * inbuf content must be writable (if bit reversal is needed) - * Returns 1 in case of success, 0 otherwise. + * This function replaces the use of + * TIFFReadEncodedStrip()/TIFFReadEncodedTile() when the user can provide the + * buffer for the input data, for example when he wants to avoid libtiff to read + * the strile offset/count values from the [Strip|Tile][Offsets/ByteCounts] + * array. inbuf content must be writable (if bit reversal is needed) Returns 1 + * in case of success, 0 otherwise. */ -int TIFFReadFromUserBuffer(TIFF* tif, uint32_t strile, - void* inbuf, tmsize_t insize, - void* outbuf, tmsize_t outsize) +int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf, + tmsize_t insize, void *outbuf, tmsize_t outsize) { static const char module[] = "TIFFReadFromUserBuffer"; TIFFDirectory *td = &tif->tif_dir; int ret = 1; uint32_t old_tif_flags = tif->tif_flags; tmsize_t old_rawdatasize = tif->tif_rawdatasize; - void* old_rawdata = tif->tif_rawdata; + void *old_rawdata = tif->tif_rawdata; - if (tif->tif_mode == O_WRONLY) { + if (tif->tif_mode == O_WRONLY) + { TIFFErrorExtR(tif, tif->tif_name, "File not open for reading"); return 0; } - if (tif->tif_flags&TIFF_NOREADRAW) + if (tif->tif_flags & TIFF_NOREADRAW) { TIFFErrorExtR(tif, module, - "Compression scheme does not support access to raw uncompressed data"); + "Compression scheme does not support access to raw " + "uncompressed data"); return 0; } @@ -1499,32 +1543,33 @@ int TIFFReadFromUserBuffer(TIFF* tif, uint32_t strile, TIFFReverseBits(inbuf, insize); } - if( TIFFIsTiled(tif) ) + if (TIFFIsTiled(tif)) { - if( !TIFFStartTile(tif, strile) || - !(*tif->tif_decodetile)(tif, (uint8_t*) outbuf, outsize, - (uint16_t)(strile / td->td_stripsperimage)) ) + if (!TIFFStartTile(tif, strile) || + !(*tif->tif_decodetile)(tif, (uint8_t *)outbuf, outsize, + (uint16_t)(strile / td->td_stripsperimage))) { ret = 0; } } else { - uint32_t rowsperstrip=td->td_rowsperstrip; + uint32_t rowsperstrip = td->td_rowsperstrip; uint32_t stripsperplane; - if (rowsperstrip>td->td_imagelength) - rowsperstrip=td->td_imagelength; - stripsperplane= TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); - if( !TIFFStartStrip(tif, strile) || - !(*tif->tif_decodestrip)(tif, (uint8_t*) outbuf, outsize, - (uint16_t)(strile / stripsperplane)) ) + if (rowsperstrip > td->td_imagelength) + rowsperstrip = td->td_imagelength; + stripsperplane = + TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip); + if (!TIFFStartStrip(tif, strile) || + !(*tif->tif_decodestrip)(tif, (uint8_t *)outbuf, outsize, + (uint16_t)(strile / stripsperplane))) { ret = 0; } } - if( ret ) + if (ret) { - (*tif->tif_postdecode)(tif, (uint8_t*) outbuf, outsize); + (*tif->tif_postdecode)(tif, (uint8_t *)outbuf, outsize); } if (!isFillOrder(tif, td->td_fillorder) && @@ -1543,40 +1588,37 @@ int TIFFReadFromUserBuffer(TIFF* tif, uint32_t strile, return ret; } -void -_TIFFNoPostDecode(TIFF* tif, uint8_t* buf, tmsize_t cc) +void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc) { - (void) tif; (void) buf; (void) cc; + (void)tif; + (void)buf; + (void)cc; } -void -_TIFFSwab16BitData(TIFF* tif, uint8_t* buf, tmsize_t cc) +void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) { - (void) tif; + (void)tif; assert((cc & 1) == 0); - TIFFSwabArrayOfShort((uint16_t*) buf, cc / 2); + TIFFSwabArrayOfShort((uint16_t *)buf, cc / 2); } -void -_TIFFSwab24BitData(TIFF* tif, uint8_t* buf, tmsize_t cc) +void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) { - (void) tif; + (void)tif; assert((cc % 3) == 0); - TIFFSwabArrayOfTriples((uint8_t*) buf, cc / 3); + TIFFSwabArrayOfTriples((uint8_t *)buf, cc / 3); } -void -_TIFFSwab32BitData(TIFF* tif, uint8_t* buf, tmsize_t cc) +void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) { - (void) tif; + (void)tif; assert((cc & 3) == 0); - TIFFSwabArrayOfLong((uint32_t*) buf, cc / 4); + TIFFSwabArrayOfLong((uint32_t *)buf, cc / 4); } -void -_TIFFSwab64BitData(TIFF* tif, uint8_t* buf, tmsize_t cc) +void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc) { - (void) tif; + (void)tif; assert((cc & 7) == 0); - TIFFSwabArrayOfDouble((double*) buf, cc/8); + TIFFSwabArrayOfDouble((double *)buf, cc / 8); } diff --git a/libtiff/tif_stream.cxx b/libtiff/tif_stream.cxx index af6c79e1..92ea273c 100644 --- a/libtiff/tif_stream.cxx +++ b/libtiff/tif_stream.cxx @@ -2,23 +2,23 @@ * Copyright (c) 1988-1996 Sam Leffler * Copyright (c) 1991-1996 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -74,345 +74,331 @@ using namespace std; struct tiffis_data; struct tiffos_data; -extern "C" { - - static tmsize_t _tiffosReadProc(thandle_t, void*, tmsize_t); - static tmsize_t _tiffisReadProc(thandle_t fd, void* buf, tmsize_t size); - static tmsize_t _tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size); - static tmsize_t _tiffisWriteProc(thandle_t, void*, tmsize_t); - static uint64_t _tiffosSeekProc(thandle_t fd, uint64_t off, int whence); - static uint64_t _tiffisSeekProc(thandle_t fd, uint64_t off, int whence); - static uint64_t _tiffosSizeProc(thandle_t fd); - static uint64_t _tiffisSizeProc(thandle_t fd); - static int _tiffosCloseProc(thandle_t fd); - static int _tiffisCloseProc(thandle_t fd); - static int _tiffDummyMapProc(thandle_t , void** base, toff_t* size ); - static void _tiffDummyUnmapProc(thandle_t , void* base, toff_t size ); - static TIFF* _tiffStreamOpen(const char* name, const char* mode, void *fd); - -struct tiffis_data +extern "C" { - istream *stream; + + static tmsize_t _tiffosReadProc(thandle_t, void *, tmsize_t); + static tmsize_t _tiffisReadProc(thandle_t fd, void *buf, tmsize_t size); + static tmsize_t _tiffosWriteProc(thandle_t fd, void *buf, tmsize_t size); + static tmsize_t _tiffisWriteProc(thandle_t, void *, tmsize_t); + static uint64_t _tiffosSeekProc(thandle_t fd, uint64_t off, int whence); + static uint64_t _tiffisSeekProc(thandle_t fd, uint64_t off, int whence); + static uint64_t _tiffosSizeProc(thandle_t fd); + static uint64_t _tiffisSizeProc(thandle_t fd); + static int _tiffosCloseProc(thandle_t fd); + static int _tiffisCloseProc(thandle_t fd); + static int _tiffDummyMapProc(thandle_t, void **base, toff_t *size); + static void _tiffDummyUnmapProc(thandle_t, void *base, toff_t size); + static TIFF *_tiffStreamOpen(const char *name, const char *mode, void *fd); + + struct tiffis_data + { + istream *stream; ios::pos_type start_pos; -}; + }; -struct tiffos_data -{ - ostream *stream; - ios::pos_type start_pos; -}; + struct tiffos_data + { + ostream *stream; + ios::pos_type start_pos; + }; -static tmsize_t -_tiffosReadProc(thandle_t, void*, tmsize_t) -{ - return 0; -} + static tmsize_t _tiffosReadProc(thandle_t, void *, tmsize_t) { return 0; } -static tmsize_t -_tiffisReadProc(thandle_t fd, void* buf, tmsize_t size) -{ - tiffis_data *data = reinterpret_cast<tiffis_data *>(fd); + static tmsize_t _tiffisReadProc(thandle_t fd, void *buf, tmsize_t size) + { + tiffis_data *data = reinterpret_cast<tiffis_data *>(fd); // Verify that type does not overflow. streamsize request_size = size; if (static_cast<tmsize_t>(request_size) != size) - return static_cast<tmsize_t>(-1); + return static_cast<tmsize_t>(-1); - data->stream->read((char *) buf, request_size); + data->stream->read((char *)buf, request_size); return static_cast<tmsize_t>(data->stream->gcount()); -} + } -static tmsize_t -_tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size) -{ - tiffos_data *data = reinterpret_cast<tiffos_data *>(fd); - ostream *os = data->stream; - ios::pos_type pos = os->tellp(); + static tmsize_t _tiffosWriteProc(thandle_t fd, void *buf, tmsize_t size) + { + tiffos_data *data = reinterpret_cast<tiffos_data *>(fd); + ostream *os = data->stream; + ios::pos_type pos = os->tellp(); // Verify that type does not overflow. streamsize request_size = size; if (static_cast<tmsize_t>(request_size) != size) - return static_cast<tmsize_t>(-1); - - os->write(reinterpret_cast<const char *>(buf), request_size); - - return static_cast<tmsize_t>(os->tellp() - pos); -} - -static tmsize_t -_tiffisWriteProc(thandle_t, void*, tmsize_t) -{ - return 0; -} - -static uint64_t -_tiffosSeekProc(thandle_t fd, uint64_t off, int whence) -{ - tiffos_data *data = reinterpret_cast<tiffos_data *>(fd); - ostream *os = data->stream; - - // if the stream has already failed, don't do anything - if( os->fail() ) - return static_cast<uint64_t>(-1); - - switch(whence) { - case SEEK_SET: - { - // Compute 64-bit offset - uint64_t new_offset = static_cast<uint64_t>(data->start_pos) + off; - - // Verify that value does not overflow - ios::off_type offset = static_cast<ios::off_type>(new_offset); - if (static_cast<uint64_t>(offset) != new_offset) - return static_cast<uint64_t>(-1); - - os->seekp(offset, ios::beg); - break; - } - case SEEK_CUR: - { - // Verify that value does not overflow - ios::off_type offset = static_cast<ios::off_type>(off); - if (static_cast<uint64_t>(offset) != off) - return static_cast<uint64_t>(-1); - - os->seekp(offset, ios::cur); - break; - } - case SEEK_END: - { - // Verify that value does not overflow - ios::off_type offset = static_cast<ios::off_type>(off); - if (static_cast<uint64_t>(offset) != off) - return static_cast<uint64_t>(-1); - - os->seekp(offset, ios::end); - break; - } - } - - // Attempt to workaround problems with seeking past the end of the - // stream. ofstream doesn't have a problem with this but - // ostrstream/ostringstream does. In that situation, add intermediate - // '\0' characters. - if( os->fail() ) { - ios::iostate old_state; - ios::pos_type origin; - - old_state = os->rdstate(); - // reset the fail bit or else tellp() won't work below - os->clear(os->rdstate() & ~ios::failbit); - switch( whence ) { - case SEEK_SET: - default: - origin = data->start_pos; - break; - case SEEK_CUR: - origin = os->tellp(); - break; - case SEEK_END: - os->seekp(0, ios::end); - origin = os->tellp(); - break; - } - // restore original stream state - os->clear(old_state); - - // only do something if desired seek position is valid - if((static_cast<uint64_t>(origin) + off) > static_cast<uint64_t>(data->start_pos) ) { - uint64_t num_fill; - - // clear the fail bit - os->clear(os->rdstate() & ~ios::failbit); - - // extend the stream to the expected size - os->seekp(0, ios::end); - num_fill = (static_cast<uint64_t>(origin)) + off - os->tellp(); - for(uint64_t i = 0; i < num_fill; i++ ) - os->put('\0'); - - // retry the seek - os->seekp(static_cast<ios::off_type>(static_cast<uint64_t>(origin) + off), ios::beg); - } - } - - return static_cast<uint64_t>(os->tellp()); -} - -static uint64_t -_tiffisSeekProc(thandle_t fd, uint64_t off, int whence) -{ - tiffis_data *data = reinterpret_cast<tiffis_data *>(fd); - - switch(whence) { - case SEEK_SET: - { - // Compute 64-bit offset - uint64_t new_offset = static_cast<uint64_t>(data->start_pos) + off; - - // Verify that value does not overflow - ios::off_type offset = static_cast<ios::off_type>(new_offset); - if (static_cast<uint64_t>(offset) != new_offset) - return static_cast<uint64_t>(-1); - - data->stream->seekg(offset, ios::beg); - break; - } - case SEEK_CUR: - { - // Verify that value does not overflow - ios::off_type offset = static_cast<ios::off_type>(off); - if (static_cast<uint64_t>(offset) != off) - return static_cast<uint64_t>(-1); - - data->stream->seekg(offset, ios::cur); - break; - } - case SEEK_END: - { - // Verify that value does not overflow - ios::off_type offset = static_cast<ios::off_type>(off); - if (static_cast<uint64_t>(offset) != off) - return static_cast<uint64_t>(-1); - - data->stream->seekg(offset, ios::end); - break; - } - } - - return (uint64_t) (data->stream->tellg() - data->start_pos); -} - -static uint64_t -_tiffosSizeProc(thandle_t fd) -{ - tiffos_data *data = reinterpret_cast<tiffos_data *>(fd); - ostream *os = data->stream; - ios::pos_type pos = os->tellp(); - ios::pos_type len; - - os->seekp(0, ios::end); - len = os->tellp(); - os->seekp(pos); - - return (uint64_t) len; -} - -static uint64_t -_tiffisSizeProc(thandle_t fd) -{ - tiffis_data *data = reinterpret_cast<tiffis_data *>(fd); - ios::pos_type pos = data->stream->tellg(); - ios::pos_type len; - - data->stream->seekg(0, ios::end); - len = data->stream->tellg(); - data->stream->seekg(pos); - - return (uint64_t) len; -} - -static int -_tiffosCloseProc(thandle_t fd) -{ - // Our stream was not allocated by us, so it shouldn't be closed by us. - delete reinterpret_cast<tiffos_data *>(fd); - return 0; -} - -static int -_tiffisCloseProc(thandle_t fd) -{ - // Our stream was not allocated by us, so it shouldn't be closed by us. - delete reinterpret_cast<tiffis_data *>(fd); - return 0; -} - -static int -_tiffDummyMapProc(thandle_t , void** base, toff_t* size ) -{ - (void) base; - (void) size; - return (0); -} - -static void -_tiffDummyUnmapProc(thandle_t , void* base, toff_t size ) -{ - (void) base; - (void) size; -} + return static_cast<tmsize_t>(-1); + + os->write(reinterpret_cast<const char *>(buf), request_size); + + return static_cast<tmsize_t>(os->tellp() - pos); + } + + static tmsize_t _tiffisWriteProc(thandle_t, void *, tmsize_t) { return 0; } + + static uint64_t _tiffosSeekProc(thandle_t fd, uint64_t off, int whence) + { + tiffos_data *data = reinterpret_cast<tiffos_data *>(fd); + ostream *os = data->stream; + + // if the stream has already failed, don't do anything + if (os->fail()) + return static_cast<uint64_t>(-1); + + switch (whence) + { + case SEEK_SET: + { + // Compute 64-bit offset + uint64_t new_offset = + static_cast<uint64_t>(data->start_pos) + off; + + // Verify that value does not overflow + ios::off_type offset = static_cast<ios::off_type>(new_offset); + if (static_cast<uint64_t>(offset) != new_offset) + return static_cast<uint64_t>(-1); + + os->seekp(offset, ios::beg); + break; + } + case SEEK_CUR: + { + // Verify that value does not overflow + ios::off_type offset = static_cast<ios::off_type>(off); + if (static_cast<uint64_t>(offset) != off) + return static_cast<uint64_t>(-1); + + os->seekp(offset, ios::cur); + break; + } + case SEEK_END: + { + // Verify that value does not overflow + ios::off_type offset = static_cast<ios::off_type>(off); + if (static_cast<uint64_t>(offset) != off) + return static_cast<uint64_t>(-1); + + os->seekp(offset, ios::end); + break; + } + } + + // Attempt to workaround problems with seeking past the end of the + // stream. ofstream doesn't have a problem with this but + // ostrstream/ostringstream does. In that situation, add intermediate + // '\0' characters. + if (os->fail()) + { + ios::iostate old_state; + ios::pos_type origin; + + old_state = os->rdstate(); + // reset the fail bit or else tellp() won't work below + os->clear(os->rdstate() & ~ios::failbit); + switch (whence) + { + case SEEK_SET: + default: + origin = data->start_pos; + break; + case SEEK_CUR: + origin = os->tellp(); + break; + case SEEK_END: + os->seekp(0, ios::end); + origin = os->tellp(); + break; + } + // restore original stream state + os->clear(old_state); + + // only do something if desired seek position is valid + if ((static_cast<uint64_t>(origin) + off) > + static_cast<uint64_t>(data->start_pos)) + { + uint64_t num_fill; + + // clear the fail bit + os->clear(os->rdstate() & ~ios::failbit); + + // extend the stream to the expected size + os->seekp(0, ios::end); + num_fill = (static_cast<uint64_t>(origin)) + off - os->tellp(); + for (uint64_t i = 0; i < num_fill; i++) + os->put('\0'); + + // retry the seek + os->seekp(static_cast<ios::off_type>( + static_cast<uint64_t>(origin) + off), + ios::beg); + } + } + + return static_cast<uint64_t>(os->tellp()); + } + + static uint64_t _tiffisSeekProc(thandle_t fd, uint64_t off, int whence) + { + tiffis_data *data = reinterpret_cast<tiffis_data *>(fd); + + switch (whence) + { + case SEEK_SET: + { + // Compute 64-bit offset + uint64_t new_offset = + static_cast<uint64_t>(data->start_pos) + off; + + // Verify that value does not overflow + ios::off_type offset = static_cast<ios::off_type>(new_offset); + if (static_cast<uint64_t>(offset) != new_offset) + return static_cast<uint64_t>(-1); + + data->stream->seekg(offset, ios::beg); + break; + } + case SEEK_CUR: + { + // Verify that value does not overflow + ios::off_type offset = static_cast<ios::off_type>(off); + if (static_cast<uint64_t>(offset) != off) + return static_cast<uint64_t>(-1); + + data->stream->seekg(offset, ios::cur); + break; + } + case SEEK_END: + { + // Verify that value does not overflow + ios::off_type offset = static_cast<ios::off_type>(off); + if (static_cast<uint64_t>(offset) != off) + return static_cast<uint64_t>(-1); + + data->stream->seekg(offset, ios::end); + break; + } + } + + return (uint64_t)(data->stream->tellg() - data->start_pos); + } + + static uint64_t _tiffosSizeProc(thandle_t fd) + { + tiffos_data *data = reinterpret_cast<tiffos_data *>(fd); + ostream *os = data->stream; + ios::pos_type pos = os->tellp(); + ios::pos_type len; + + os->seekp(0, ios::end); + len = os->tellp(); + os->seekp(pos); + + return (uint64_t)len; + } + + static uint64_t _tiffisSizeProc(thandle_t fd) + { + tiffis_data *data = reinterpret_cast<tiffis_data *>(fd); + ios::pos_type pos = data->stream->tellg(); + ios::pos_type len; + + data->stream->seekg(0, ios::end); + len = data->stream->tellg(); + data->stream->seekg(pos); + + return (uint64_t)len; + } + + static int _tiffosCloseProc(thandle_t fd) + { + // Our stream was not allocated by us, so it shouldn't be closed by us. + delete reinterpret_cast<tiffos_data *>(fd); + return 0; + } -/* - * Open a TIFF file descriptor for read/writing. - */ -static TIFF* -_tiffStreamOpen(const char* name, const char* mode, void *fd) -{ - TIFF* tif; - - if( strchr(mode, 'w') ) { - tiffos_data *data = new tiffos_data; - data->stream = reinterpret_cast<ostream *>(fd); - data->start_pos = data->stream->tellp(); - - // Open for writing. - tif = TIFFClientOpen(name, mode, - reinterpret_cast<thandle_t>(data), - _tiffosReadProc, - _tiffosWriteProc, - _tiffosSeekProc, - _tiffosCloseProc, - _tiffosSizeProc, - _tiffDummyMapProc, - _tiffDummyUnmapProc); - if (!tif) { - delete data; - } - } else { - tiffis_data *data = new tiffis_data; - data->stream = reinterpret_cast<istream *>(fd); - data->start_pos = data->stream->tellg(); - // Open for reading. - tif = TIFFClientOpen(name, mode, - reinterpret_cast<thandle_t>(data), - _tiffisReadProc, - _tiffisWriteProc, - _tiffisSeekProc, - _tiffisCloseProc, - _tiffisSizeProc, - _tiffDummyMapProc, - _tiffDummyUnmapProc); - if (!tif) { - delete data; - } - } - - return (tif); -} + static int _tiffisCloseProc(thandle_t fd) + { + // Our stream was not allocated by us, so it shouldn't be closed by us. + delete reinterpret_cast<tiffis_data *>(fd); + return 0; + } + + static int _tiffDummyMapProc(thandle_t, void **base, toff_t *size) + { + (void)base; + (void)size; + return (0); + } + + static void _tiffDummyUnmapProc(thandle_t, void *base, toff_t size) + { + (void)base; + (void)size; + } + + /* + * Open a TIFF file descriptor for read/writing. + */ + static TIFF *_tiffStreamOpen(const char *name, const char *mode, void *fd) + { + TIFF *tif; + + if (strchr(mode, 'w')) + { + tiffos_data *data = new tiffos_data; + data->stream = reinterpret_cast<ostream *>(fd); + data->start_pos = data->stream->tellp(); + + // Open for writing. + tif = TIFFClientOpen( + name, mode, reinterpret_cast<thandle_t>(data), _tiffosReadProc, + _tiffosWriteProc, _tiffosSeekProc, _tiffosCloseProc, + _tiffosSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc); + if (!tif) + { + delete data; + } + } + else + { + tiffis_data *data = new tiffis_data; + data->stream = reinterpret_cast<istream *>(fd); + data->start_pos = data->stream->tellg(); + // Open for reading. + tif = TIFFClientOpen( + name, mode, reinterpret_cast<thandle_t>(data), _tiffisReadProc, + _tiffisWriteProc, _tiffisSeekProc, _tiffisCloseProc, + _tiffisSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc); + if (!tif) + { + delete data; + } + } + + return (tif); + } } /* extern "C" */ -TIFF* -TIFFStreamOpen(const char* name, ostream *os) +TIFF *TIFFStreamOpen(const char *name, ostream *os) { - // If os is either a ostrstream or ostringstream, and has no data - // written to it yet, then tellp() will return -1 which will break us. - // We workaround this by writing out a dummy character and - // then seek back to the beginning. - if( !os->fail() && static_cast<int>(os->tellp()) < 0 ) { - *os << '\0'; - os->seekp(0); - } - - // NB: We don't support mapped files with streams so add 'm' - return _tiffStreamOpen(name, "wm", os); + // If os is either a ostrstream or ostringstream, and has no data + // written to it yet, then tellp() will return -1 which will break us. + // We workaround this by writing out a dummy character and + // then seek back to the beginning. + if (!os->fail() && static_cast<int>(os->tellp()) < 0) + { + *os << '\0'; + os->seekp(0); + } + + // NB: We don't support mapped files with streams so add 'm' + return _tiffStreamOpen(name, "wm", os); } -TIFF* -TIFFStreamOpen(const char* name, istream *is) +TIFF *TIFFStreamOpen(const char *name, istream *is) { - // NB: We don't support mapped files with streams so add 'm' - return _tiffStreamOpen(name, "rm", is); + // NB: We don't support mapped files with streams so add 'm' + return _tiffStreamOpen(name, "rm", is); } diff --git a/libtiff/tif_strip.c b/libtiff/tif_strip.c index 62f11bf7..820a2544 100644 --- a/libtiff/tif_strip.c +++ b/libtiff/tif_strip.c @@ -2,23 +2,23 @@ * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -32,146 +32,145 @@ /* * Compute which strip a (row,sample) value is in. */ -uint32_t -TIFFComputeStrip(TIFF* tif, uint32_t row, uint16_t sample) +uint32_t TIFFComputeStrip(TIFF *tif, uint32_t row, uint16_t sample) { - static const char module[] = "TIFFComputeStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint32_t strip; + static const char module[] = "TIFFComputeStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint32_t strip; - strip = row / td->td_rowsperstrip; - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - if (sample >= td->td_samplesperpixel) { - TIFFErrorExtR(tif, module, - "%lu: Sample out of range, max %lu", - (unsigned long) sample, (unsigned long) td->td_samplesperpixel); - return (0); - } - strip += (uint32_t)sample * td->td_stripsperimage; - } - return (strip); + strip = row / td->td_rowsperstrip; + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + if (sample >= td->td_samplesperpixel) + { + TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu", + (unsigned long)sample, + (unsigned long)td->td_samplesperpixel); + return (0); + } + strip += (uint32_t)sample * td->td_stripsperimage; + } + return (strip); } /* * Compute how many strips are in an image. */ -uint32_t -TIFFNumberOfStrips(TIFF* tif) +uint32_t TIFFNumberOfStrips(TIFF *tif) { - TIFFDirectory *td = &tif->tif_dir; - uint32_t nstrips; + TIFFDirectory *td = &tif->tif_dir; + uint32_t nstrips; - nstrips = (td->td_rowsperstrip == (uint32_t) -1 ? 1 : - TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - nstrips = _TIFFMultiply32(tif, nstrips, (uint32_t)td->td_samplesperpixel, - "TIFFNumberOfStrips"); - return (nstrips); + nstrips = (td->td_rowsperstrip == (uint32_t)-1 + ? 1 + : TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip)); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + nstrips = + _TIFFMultiply32(tif, nstrips, (uint32_t)td->td_samplesperpixel, + "TIFFNumberOfStrips"); + return (nstrips); } /* * Compute the # bytes in a variable height, row-aligned strip. */ -uint64_t -TIFFVStripSize64(TIFF* tif, uint32_t nrows) +uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows) { - static const char module[] = "TIFFVStripSize64"; - TIFFDirectory *td = &tif->tif_dir; - if (nrows==(uint32_t)(-1)) - nrows=td->td_imagelength; - if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& - (td->td_photometric == PHOTOMETRIC_YCBCR)&& - (!isUpSampled(tif))) - { - /* - * Packed YCbCr data contain one Cb+Cr for every - * HorizontalSampling*VerticalSampling Y values. - * Must also roundup width and height when calculating - * since images that are not a multiple of the - * horizontal/vertical subsampling area include - * YCbCr data for the extended image. - */ - uint16_t ycbcrsubsampling[2]; - uint16_t samplingblock_samples; - uint32_t samplingblocks_hor; - uint32_t samplingblocks_ver; - uint64_t samplingrow_samples; - uint64_t samplingrow_size; - if(td->td_samplesperpixel!=3) - { - TIFFErrorExtR(tif,module, - "Invalid td_samplesperpixel value"); - return 0; - } - TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, - ycbcrsubsampling+1); - if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4) - ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4)) - { - TIFFErrorExtR(tif,module, - "Invalid YCbCr subsampling (%dx%d)", - ycbcrsubsampling[0], - ycbcrsubsampling[1] ); - return 0; - } - samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; - samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]); - samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); - samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); - samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module)); - return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module)); - } - else - return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module)); + static const char module[] = "TIFFVStripSize64"; + TIFFDirectory *td = &tif->tif_dir; + if (nrows == (uint32_t)(-1)) + nrows = td->td_imagelength; + if ((td->td_planarconfig == PLANARCONFIG_CONTIG) && + (td->td_photometric == PHOTOMETRIC_YCBCR) && (!isUpSampled(tif))) + { + /* + * Packed YCbCr data contain one Cb+Cr for every + * HorizontalSampling*VerticalSampling Y values. + * Must also roundup width and height when calculating + * since images that are not a multiple of the + * horizontal/vertical subsampling area include + * YCbCr data for the extended image. + */ + uint16_t ycbcrsubsampling[2]; + uint16_t samplingblock_samples; + uint32_t samplingblocks_hor; + uint32_t samplingblocks_ver; + uint64_t samplingrow_samples; + uint64_t samplingrow_size; + if (td->td_samplesperpixel != 3) + { + TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value"); + return 0; + } + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, + ycbcrsubsampling + 0, ycbcrsubsampling + 1); + if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && + ycbcrsubsampling[0] != 4) || + (ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && + ycbcrsubsampling[1] != 4)) + { + TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)", + ycbcrsubsampling[0], ycbcrsubsampling[1]); + return 0; + } + samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2; + samplingblocks_hor = + TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]); + samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]); + samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor, + samplingblock_samples, module); + samplingrow_size = TIFFhowmany8_64(_TIFFMultiply64( + tif, samplingrow_samples, td->td_bitspersample, module)); + return ( + _TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module)); + } + else + return (_TIFFMultiply64(tif, nrows, TIFFScanlineSize64(tif), module)); } -tmsize_t -TIFFVStripSize(TIFF* tif, uint32_t nrows) +tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows) { - static const char module[] = "TIFFVStripSize"; - uint64_t m; - m=TIFFVStripSize64(tif,nrows); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFVStripSize"; + uint64_t m; + m = TIFFVStripSize64(tif, nrows); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* * Compute the # bytes in a raw strip. */ -uint64_t -TIFFRawStripSize64(TIFF* tif, uint32_t strip) +uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip) { - static const char module[] = "TIFFRawStripSize64"; - uint64_t bytecount = TIFFGetStrileByteCount(tif, strip); + static const char module[] = "TIFFRawStripSize64"; + uint64_t bytecount = TIFFGetStrileByteCount(tif, strip); - if (bytecount == 0) - { - TIFFErrorExtR(tif, module, - "%"PRIu64": Invalid strip byte count, strip %lu", - (uint64_t) bytecount, - (unsigned long) strip); - bytecount = (uint64_t) -1; - } + if (bytecount == 0) + { + TIFFErrorExtR(tif, module, + "%" PRIu64 ": Invalid strip byte count, strip %lu", + (uint64_t)bytecount, (unsigned long)strip); + bytecount = (uint64_t)-1; + } - return bytecount; + return bytecount; } -tmsize_t -TIFFRawStripSize(TIFF* tif, uint32_t strip) +tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip) { - static const char module[] = "TIFFRawStripSize"; - uint64_t m; - tmsize_t n; - m=TIFFRawStripSize64(tif,strip); - if (m==(uint64_t)(-1)) - n=(tmsize_t)(-1); - else - { - n=(tmsize_t)m; - if ((uint64_t)n != m) - { - TIFFErrorExtR(tif,module,"Integer overflow"); - n=0; - } - } - return(n); + static const char module[] = "TIFFRawStripSize"; + uint64_t m; + tmsize_t n; + m = TIFFRawStripSize64(tif, strip); + if (m == (uint64_t)(-1)) + n = (tmsize_t)(-1); + else + { + n = (tmsize_t)m; + if ((uint64_t)n != m) + { + TIFFErrorExtR(tif, module, "Integer overflow"); + n = 0; + } + } + return (n); } /* @@ -182,22 +181,20 @@ TIFFRawStripSize(TIFF* tif, uint32_t strip) * truncated to reflect the actual space required * to hold the strip. */ -uint64_t -TIFFStripSize64(TIFF* tif) +uint64_t TIFFStripSize64(TIFF *tif) { - TIFFDirectory* td = &tif->tif_dir; - uint32_t rps = td->td_rowsperstrip; - if (rps > td->td_imagelength) - rps = td->td_imagelength; - return (TIFFVStripSize64(tif, rps)); + TIFFDirectory *td = &tif->tif_dir; + uint32_t rps = td->td_rowsperstrip; + if (rps > td->td_imagelength) + rps = td->td_imagelength; + return (TIFFVStripSize64(tif, rps)); } -tmsize_t -TIFFStripSize(TIFF* tif) +tmsize_t TIFFStripSize(TIFF *tif) { - static const char module[] = "TIFFStripSize"; - uint64_t m; - m=TIFFStripSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFStripSize"; + uint64_t m; + m = TIFFStripSize64(tif); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* @@ -206,34 +203,33 @@ TIFFStripSize(TIFF* tif) * request is <1 then we choose a strip size according * to certain heuristics. */ -uint32_t -TIFFDefaultStripSize(TIFF* tif, uint32_t request) +uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request) { - return (*tif->tif_defstripsize)(tif, request); + return (*tif->tif_defstripsize)(tif, request); } -uint32_t -_TIFFDefaultStripSize(TIFF* tif, uint32_t s) +uint32_t _TIFFDefaultStripSize(TIFF *tif, uint32_t s) { - if ((int32_t) s < 1) { - /* - * If RowsPerStrip is unspecified, try to break the - * image up into strips that are approximately - * STRIP_SIZE_DEFAULT bytes long. - */ - uint64_t scanlinesize; - uint64_t rows; - scanlinesize=TIFFScanlineSize64(tif); - if (scanlinesize==0) - scanlinesize=1; - rows= (uint64_t)STRIP_SIZE_DEFAULT / scanlinesize; - if (rows==0) - rows=1; - else if (rows>0xFFFFFFFF) - rows=0xFFFFFFFF; - s=(uint32_t)rows; - } - return (s); + if ((int32_t)s < 1) + { + /* + * If RowsPerStrip is unspecified, try to break the + * image up into strips that are approximately + * STRIP_SIZE_DEFAULT bytes long. + */ + uint64_t scanlinesize; + uint64_t rows; + scanlinesize = TIFFScanlineSize64(tif); + if (scanlinesize == 0) + scanlinesize = 1; + rows = (uint64_t)STRIP_SIZE_DEFAULT / scanlinesize; + if (rows == 0) + rows = 1; + else if (rows > 0xFFFFFFFF) + rows = 0xFFFFFFFF; + s = (uint32_t)rows; + } + return (s); } /* @@ -246,70 +242,79 @@ _TIFFDefaultStripSize(TIFF* tif, uint32_t s) * subsampling lines divided by vertical subsampling. It should thus make * sense when multiplied by a multiple of vertical subsampling. */ -uint64_t -TIFFScanlineSize64(TIFF* tif) +uint64_t TIFFScanlineSize64(TIFF *tif) { - static const char module[] = "TIFFScanlineSize64"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t scanline_size; - if (td->td_planarconfig==PLANARCONFIG_CONTIG) - { - if ((td->td_photometric==PHOTOMETRIC_YCBCR)&& - (td->td_samplesperpixel==3)&& - (!isUpSampled(tif))) - { - uint16_t ycbcrsubsampling[2]; - uint16_t samplingblock_samples; - uint32_t samplingblocks_hor; - uint64_t samplingrow_samples; - uint64_t samplingrow_size; - if(td->td_samplesperpixel!=3) - { - TIFFErrorExtR(tif,module, - "Invalid td_samplesperpixel value"); - return 0; - } - TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING, - ycbcrsubsampling+0, - ycbcrsubsampling+1); - if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) || - ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4))) - { - TIFFErrorExtR(tif,module, - "Invalid YCbCr subsampling"); - return 0; - } - samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; - samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]); - samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); - samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8); - scanline_size = (samplingrow_size/ycbcrsubsampling[1]); - } - else - { - uint64_t scanline_samples; - scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module); - scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8); - } - } - else + static const char module[] = "TIFFScanlineSize64"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t scanline_size; + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + if ((td->td_photometric == PHOTOMETRIC_YCBCR) && + (td->td_samplesperpixel == 3) && (!isUpSampled(tif))) { - scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8); + uint16_t ycbcrsubsampling[2]; + uint16_t samplingblock_samples; + uint32_t samplingblocks_hor; + uint64_t samplingrow_samples; + uint64_t samplingrow_size; + if (td->td_samplesperpixel != 3) + { + TIFFErrorExtR(tif, module, "Invalid td_samplesperpixel value"); + return 0; + } + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, + ycbcrsubsampling + 0, ycbcrsubsampling + 1); + if (((ycbcrsubsampling[0] != 1) && (ycbcrsubsampling[0] != 2) && + (ycbcrsubsampling[0] != 4)) || + ((ycbcrsubsampling[1] != 1) && (ycbcrsubsampling[1] != 2) && + (ycbcrsubsampling[1] != 4))) + { + TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling"); + return 0; + } + samplingblock_samples = + ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2; + samplingblocks_hor = + TIFFhowmany_32(td->td_imagewidth, ycbcrsubsampling[0]); + samplingrow_samples = _TIFFMultiply64( + tif, samplingblocks_hor, samplingblock_samples, module); + samplingrow_size = + TIFFhowmany_64(_TIFFMultiply64(tif, samplingrow_samples, + td->td_bitspersample, module), + 8); + scanline_size = (samplingrow_size / ycbcrsubsampling[1]); } - if (scanline_size == 0) + else { - TIFFErrorExtR(tif,module,"Computed scanline size is zero"); - return 0; + uint64_t scanline_samples; + scanline_samples = _TIFFMultiply64(tif, td->td_imagewidth, + td->td_samplesperpixel, module); + scanline_size = + TIFFhowmany_64(_TIFFMultiply64(tif, scanline_samples, + td->td_bitspersample, module), + 8); } - return(scanline_size); + } + else + { + scanline_size = + TIFFhowmany_64(_TIFFMultiply64(tif, td->td_imagewidth, + td->td_bitspersample, module), + 8); + } + if (scanline_size == 0) + { + TIFFErrorExtR(tif, module, "Computed scanline size is zero"); + return 0; + } + return (scanline_size); } -tmsize_t -TIFFScanlineSize(TIFF* tif) +tmsize_t TIFFScanlineSize(TIFF *tif) { - static const char module[] = "TIFFScanlineSize"; - uint64_t m; - m=TIFFScanlineSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFScanlineSize"; + uint64_t m; + m = TIFFScanlineSize64(tif); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* @@ -318,26 +323,28 @@ TIFFScanlineSize(TIFF* tif) * I/O size returned by TIFFScanlineSize which may be less * if data is store as separate planes). */ -uint64_t -TIFFRasterScanlineSize64(TIFF* tif) +uint64_t TIFFRasterScanlineSize64(TIFF *tif) { - static const char module[] = "TIFFRasterScanlineSize64"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t scanline; + static const char module[] = "TIFFRasterScanlineSize64"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t scanline; - scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module); - if (td->td_planarconfig == PLANARCONFIG_CONTIG) { - scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module); - return (TIFFhowmany8_64(scanline)); - } else - return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline), - td->td_samplesperpixel, module)); + scanline = + _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module); + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + scanline = + _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module); + return (TIFFhowmany8_64(scanline)); + } + else + return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline), + td->td_samplesperpixel, module)); } -tmsize_t -TIFFRasterScanlineSize(TIFF* tif) +tmsize_t TIFFRasterScanlineSize(TIFF *tif) { - static const char module[] = "TIFFRasterScanlineSize"; - uint64_t m; - m=TIFFRasterScanlineSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFRasterScanlineSize"; + uint64_t m; + m = TIFFRasterScanlineSize64(tif); + return _TIFFCastUInt64ToSSize(tif, m, module); } diff --git a/libtiff/tif_swab.c b/libtiff/tif_swab.c index 977eb988..827b025c 100644 --- a/libtiff/tif_swab.c +++ b/libtiff/tif_swab.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -30,169 +30,218 @@ #include "tiffiop.h" #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabShort) -void -TIFFSwabShort(uint16_t* wp) +void TIFFSwabShort(uint16_t *wp) { - register unsigned char* cp = (unsigned char*) wp; - unsigned char t; - assert(sizeof(uint16_t) == 2); - t = cp[1]; cp[1] = cp[0]; cp[0] = t; + register unsigned char *cp = (unsigned char *)wp; + unsigned char t; + assert(sizeof(uint16_t) == 2); + t = cp[1]; + cp[1] = cp[0]; + cp[0] = t; } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong) -void -TIFFSwabLong(uint32_t* lp) +void TIFFSwabLong(uint32_t *lp) { - register unsigned char* cp = (unsigned char*) lp; - unsigned char t; - assert(sizeof(uint32_t) == 4); - t = cp[3]; cp[3] = cp[0]; cp[0] = t; - t = cp[2]; cp[2] = cp[1]; cp[1] = t; + register unsigned char *cp = (unsigned char *)lp; + unsigned char t; + assert(sizeof(uint32_t) == 4); + t = cp[3]; + cp[3] = cp[0]; + cp[0] = t; + t = cp[2]; + cp[2] = cp[1]; + cp[1] = t; } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabLong8) -void -TIFFSwabLong8(uint64_t* lp) +void TIFFSwabLong8(uint64_t *lp) { - register unsigned char* cp = (unsigned char*) lp; - unsigned char t; - assert(sizeof(uint64_t) == 8); - t = cp[7]; cp[7] = cp[0]; cp[0] = t; - t = cp[6]; cp[6] = cp[1]; cp[1] = t; - t = cp[5]; cp[5] = cp[2]; cp[2] = t; - t = cp[4]; cp[4] = cp[3]; cp[3] = t; + register unsigned char *cp = (unsigned char *)lp; + unsigned char t; + assert(sizeof(uint64_t) == 8); + t = cp[7]; + cp[7] = cp[0]; + cp[0] = t; + t = cp[6]; + cp[6] = cp[1]; + cp[1] = t; + t = cp[5]; + cp[5] = cp[2]; + cp[2] = t; + t = cp[4]; + cp[4] = cp[3]; + cp[3] = t; } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfShort) -void -TIFFSwabArrayOfShort(register uint16_t* wp, tmsize_t n) +void TIFFSwabArrayOfShort(register uint16_t *wp, tmsize_t n) { - register unsigned char* cp; - register unsigned char t; - assert(sizeof(uint16_t) == 2); - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char*) wp; - t = cp[1]; cp[1] = cp[0]; cp[0] = t; - wp++; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(uint16_t) == 2); + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)wp; + t = cp[1]; + cp[1] = cp[0]; + cp[0] = t; + wp++; + } } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfTriples) -void -TIFFSwabArrayOfTriples(register uint8_t* tp, tmsize_t n) +void TIFFSwabArrayOfTriples(register uint8_t *tp, tmsize_t n) { - unsigned char* cp; - unsigned char t; + unsigned char *cp; + unsigned char t; - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char*) tp; - t = cp[2]; cp[2] = cp[0]; cp[0] = t; - tp += 3; - } + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)tp; + t = cp[2]; + cp[2] = cp[0]; + cp[0] = t; + tp += 3; + } } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong) -void -TIFFSwabArrayOfLong(register uint32_t* lp, tmsize_t n) +void TIFFSwabArrayOfLong(register uint32_t *lp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; - assert(sizeof(uint32_t) == 4); - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char *)lp; - t = cp[3]; cp[3] = cp[0]; cp[0] = t; - t = cp[2]; cp[2] = cp[1]; cp[1] = t; - lp++; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(uint32_t) == 4); + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)lp; + t = cp[3]; + cp[3] = cp[0]; + cp[0] = t; + t = cp[2]; + cp[2] = cp[1]; + cp[1] = t; + lp++; + } } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfLong8) -void -TIFFSwabArrayOfLong8(register uint64_t* lp, tmsize_t n) +void TIFFSwabArrayOfLong8(register uint64_t *lp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; - assert(sizeof(uint64_t) == 8); - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char *)lp; - t = cp[7]; cp[7] = cp[0]; cp[0] = t; - t = cp[6]; cp[6] = cp[1]; cp[1] = t; - t = cp[5]; cp[5] = cp[2]; cp[2] = t; - t = cp[4]; cp[4] = cp[3]; cp[3] = t; - lp++; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(uint64_t) == 8); + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)lp; + t = cp[7]; + cp[7] = cp[0]; + cp[0] = t; + t = cp[6]; + cp[6] = cp[1]; + cp[1] = t; + t = cp[5]; + cp[5] = cp[2]; + cp[2] = t; + t = cp[4]; + cp[4] = cp[3]; + cp[3] = t; + lp++; + } } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabFloat) -void -TIFFSwabFloat(float* fp) +void TIFFSwabFloat(float *fp) { - register unsigned char* cp = (unsigned char*) fp; - unsigned char t; - assert(sizeof(float)==4); - t = cp[3]; cp[3] = cp[0]; cp[0] = t; - t = cp[2]; cp[2] = cp[1]; cp[1] = t; + register unsigned char *cp = (unsigned char *)fp; + unsigned char t; + assert(sizeof(float) == 4); + t = cp[3]; + cp[3] = cp[0]; + cp[0] = t; + t = cp[2]; + cp[2] = cp[1]; + cp[1] = t; } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfFloat) -void -TIFFSwabArrayOfFloat(register float* fp, tmsize_t n) +void TIFFSwabArrayOfFloat(register float *fp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; - assert(sizeof(float)==4); - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char *)fp; - t = cp[3]; cp[3] = cp[0]; cp[0] = t; - t = cp[2]; cp[2] = cp[1]; cp[1] = t; - fp++; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(float) == 4); + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)fp; + t = cp[3]; + cp[3] = cp[0]; + cp[0] = t; + t = cp[2]; + cp[2] = cp[1]; + cp[1] = t; + fp++; + } } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabDouble) -void -TIFFSwabDouble(double *dp) +void TIFFSwabDouble(double *dp) { - register unsigned char* cp = (unsigned char*) dp; - unsigned char t; - assert(sizeof(double)==8); - t = cp[7]; cp[7] = cp[0]; cp[0] = t; - t = cp[6]; cp[6] = cp[1]; cp[1] = t; - t = cp[5]; cp[5] = cp[2]; cp[2] = t; - t = cp[4]; cp[4] = cp[3]; cp[3] = t; + register unsigned char *cp = (unsigned char *)dp; + unsigned char t; + assert(sizeof(double) == 8); + t = cp[7]; + cp[7] = cp[0]; + cp[0] = t; + t = cp[6]; + cp[6] = cp[1]; + cp[1] = t; + t = cp[5]; + cp[5] = cp[2]; + cp[2] = t; + t = cp[4]; + cp[4] = cp[3]; + cp[3] = t; } #endif #if defined(DISABLE_CHECK_TIFFSWABMACROS) || !defined(TIFFSwabArrayOfDouble) -void -TIFFSwabArrayOfDouble(double* dp, tmsize_t n) +void TIFFSwabArrayOfDouble(double *dp, tmsize_t n) { - register unsigned char *cp; - register unsigned char t; - assert(sizeof(double)==8); - /* XXX unroll loop some */ - while (n-- > 0) { - cp = (unsigned char *)dp; - t = cp[7]; cp[7] = cp[0]; cp[0] = t; - t = cp[6]; cp[6] = cp[1]; cp[1] = t; - t = cp[5]; cp[5] = cp[2]; cp[2] = t; - t = cp[4]; cp[4] = cp[3]; cp[3] = t; - dp++; - } + register unsigned char *cp; + register unsigned char t; + assert(sizeof(double) == 8); + /* XXX unroll loop some */ + while (n-- > 0) + { + cp = (unsigned char *)dp; + t = cp[7]; + cp[7] = cp[0]; + cp[0] = t; + t = cp[6]; + cp[6] = cp[1]; + cp[1] = t; + t = cp[5]; + cp[5] = cp[2]; + cp[2] = t; + t = cp[4]; + cp[4] = cp[3]; + cp[3] = t; + dp++; + } } #endif @@ -206,96 +255,75 @@ TIFFSwabArrayOfDouble(double* dp, tmsize_t n) * do not reverse bit values. */ static const unsigned char TIFFBitRevTable[256] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff -}; + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, + 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, + 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, + 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, + 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, + 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, + 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, + 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, + 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, + 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, + 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, + 0x3f, 0xbf, 0x7f, 0xff}; static const unsigned char TIFFNoBitRevTable[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, + 0xfc, 0xfd, 0xfe, 0xff, }; -const unsigned char* -TIFFGetBitRevTable(int reversed) +const unsigned char *TIFFGetBitRevTable(int reversed) { - return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable); + return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable); } -void -TIFFReverseBits(uint8_t* cp, tmsize_t n) +void TIFFReverseBits(uint8_t *cp, tmsize_t n) { - for (; n > 8; n -= 8) { - cp[0] = TIFFBitRevTable[cp[0]]; - cp[1] = TIFFBitRevTable[cp[1]]; - cp[2] = TIFFBitRevTable[cp[2]]; - cp[3] = TIFFBitRevTable[cp[3]]; - cp[4] = TIFFBitRevTable[cp[4]]; - cp[5] = TIFFBitRevTable[cp[5]]; - cp[6] = TIFFBitRevTable[cp[6]]; - cp[7] = TIFFBitRevTable[cp[7]]; - cp += 8; - } - while (n-- > 0) { - *cp = TIFFBitRevTable[*cp]; - cp++; - } + for (; n > 8; n -= 8) + { + cp[0] = TIFFBitRevTable[cp[0]]; + cp[1] = TIFFBitRevTable[cp[1]]; + cp[2] = TIFFBitRevTable[cp[2]]; + cp[3] = TIFFBitRevTable[cp[3]]; + cp[4] = TIFFBitRevTable[cp[4]]; + cp[5] = TIFFBitRevTable[cp[5]]; + cp[6] = TIFFBitRevTable[cp[6]]; + cp[7] = TIFFBitRevTable[cp[7]]; + cp += 8; + } + while (n-- > 0) + { + *cp = TIFFBitRevTable[*cp]; + cp++; + } } diff --git a/libtiff/tif_thunder.c b/libtiff/tif_thunder.c index 965a5ab8..1f97362c 100644 --- a/libtiff/tif_thunder.c +++ b/libtiff/tif_thunder.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -41,148 +41,158 @@ * or 3-bit delta values are used, with the deltas packed * into a single byte. */ -#define THUNDER_DATA 0x3f /* mask for 6-bit data */ -#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */ +#define THUNDER_DATA 0x3f /* mask for 6-bit data */ +#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */ /* code values */ -#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */ -#define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */ -#define DELTA2_SKIP 2 /* skip code for 2-bit deltas */ -#define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */ -#define DELTA3_SKIP 4 /* skip code for 3-bit deltas */ -#define THUNDER_RAW 0xc0 /* raw data encoded */ +#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */ +#define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */ +#define DELTA2_SKIP 2 /* skip code for 2-bit deltas */ +#define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */ +#define DELTA3_SKIP 4 /* skip code for 3-bit deltas */ +#define THUNDER_RAW 0xc0 /* raw data encoded */ -static const int twobitdeltas[4] = { 0, 1, 0, -1 }; -static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 }; +static const int twobitdeltas[4] = {0, 1, 0, -1}; +static const int threebitdeltas[8] = {0, 1, 2, 3, 0, -3, -2, -1}; -#define SETPIXEL(op, v) { \ - lastpixel = (v) & 0xf; \ - if ( npixels < maxpixels ) \ - { \ - if (npixels++ & 1) \ - *op++ |= lastpixel; \ - else \ - op[0] = (uint8_t) (lastpixel << 4); \ - } \ -} +#define SETPIXEL(op, v) \ + { \ + lastpixel = (v)&0xf; \ + if (npixels < maxpixels) \ + { \ + if (npixels++ & 1) \ + *op++ |= lastpixel; \ + else \ + op[0] = (uint8_t)(lastpixel << 4); \ + } \ + } -static int -ThunderSetupDecode(TIFF* tif) +static int ThunderSetupDecode(TIFF *tif) { - static const char module[] = "ThunderSetupDecode"; + static const char module[] = "ThunderSetupDecode"; - if( tif->tif_dir.td_bitspersample != 4 ) - { - TIFFErrorExtR(tif, module, - "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.", - (int) tif->tif_dir.td_bitspersample ); - return 0; - } - + if (tif->tif_dir.td_bitspersample != 4) + { + TIFFErrorExtR(tif, module, + "Wrong bitspersample value (%d), Thunder decoder only " + "supports 4bits per sample.", + (int)tif->tif_dir.td_bitspersample); + return 0; + } - return (1); + return (1); } -static int -ThunderDecode(TIFF* tif, uint8_t* op, tmsize_t maxpixels) +static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels) { - static const char module[] = "ThunderDecode"; - register unsigned char *bp; - register tmsize_t cc; - unsigned int lastpixel; - tmsize_t npixels; + static const char module[] = "ThunderDecode"; + register unsigned char *bp; + register tmsize_t cc; + unsigned int lastpixel; + tmsize_t npixels; - bp = (unsigned char *)tif->tif_rawcp; - cc = tif->tif_rawcc; - lastpixel = 0; - npixels = 0; - while (cc > 0 && npixels < maxpixels) { - int n, delta; + bp = (unsigned char *)tif->tif_rawcp; + cc = tif->tif_rawcc; + lastpixel = 0; + npixels = 0; + while (cc > 0 && npixels < maxpixels) + { + int n, delta; - n = *bp++; - cc--; - switch (n & THUNDER_CODE) { - case THUNDER_RUN: /* pixel run */ - /* - * Replicate the last pixel n times, - * where n is the lower-order 6 bits. - */ - if (npixels & 1) { - op[0] |= lastpixel; - lastpixel = *op++; npixels++; n--; - } else - lastpixel |= lastpixel << 4; - npixels += n; - if (npixels < maxpixels) { - for (; n > 0; n -= 2) - *op++ = (uint8_t) lastpixel; - } - if (n == -1) - *--op &= 0xf0; - lastpixel &= 0xf; - break; - case THUNDER_2BITDELTAS: /* 2-bit deltas */ - if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP) - SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta])); - if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP) - SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta])); - if ((delta = (n & 3)) != DELTA2_SKIP) - SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta])); - break; - case THUNDER_3BITDELTAS: /* 3-bit deltas */ - if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP) - SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta])); - if ((delta = (n & 7)) != DELTA3_SKIP) - SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta])); - break; - case THUNDER_RAW: /* raw data */ - SETPIXEL(op, n); - break; - } - } - tif->tif_rawcp = (uint8_t*) bp; - tif->tif_rawcc = cc; - if (npixels != maxpixels) { - TIFFErrorExtR(tif, module, - "%s data at scanline %lu (%"PRIu64" != %"PRIu64")", - npixels < maxpixels ? "Not enough" : "Too much", - (unsigned long) tif->tif_row, - (uint64_t) npixels, - (uint64_t) maxpixels); - return (0); - } + n = *bp++; + cc--; + switch (n & THUNDER_CODE) + { + case THUNDER_RUN: /* pixel run */ + /* + * Replicate the last pixel n times, + * where n is the lower-order 6 bits. + */ + if (npixels & 1) + { + op[0] |= lastpixel; + lastpixel = *op++; + npixels++; + n--; + } + else + lastpixel |= lastpixel << 4; + npixels += n; + if (npixels < maxpixels) + { + for (; n > 0; n -= 2) + *op++ = (uint8_t)lastpixel; + } + if (n == -1) + *--op &= 0xf0; + lastpixel &= 0xf; + break; + case THUNDER_2BITDELTAS: /* 2-bit deltas */ + if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP) + SETPIXEL(op, + (unsigned)((int)lastpixel + twobitdeltas[delta])); + if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP) + SETPIXEL(op, + (unsigned)((int)lastpixel + twobitdeltas[delta])); + if ((delta = (n & 3)) != DELTA2_SKIP) + SETPIXEL(op, + (unsigned)((int)lastpixel + twobitdeltas[delta])); + break; + case THUNDER_3BITDELTAS: /* 3-bit deltas */ + if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP) + SETPIXEL( + op, (unsigned)((int)lastpixel + threebitdeltas[delta])); + if ((delta = (n & 7)) != DELTA3_SKIP) + SETPIXEL( + op, (unsigned)((int)lastpixel + threebitdeltas[delta])); + break; + case THUNDER_RAW: /* raw data */ + SETPIXEL(op, n); + break; + } + } + tif->tif_rawcp = (uint8_t *)bp; + tif->tif_rawcc = cc; + if (npixels != maxpixels) + { + TIFFErrorExtR(tif, module, + "%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")", + npixels < maxpixels ? "Not enough" : "Too much", + (unsigned long)tif->tif_row, (uint64_t)npixels, + (uint64_t)maxpixels); + return (0); + } - return (1); + return (1); } -static int -ThunderDecodeRow(TIFF* tif, uint8_t* buf, tmsize_t occ, uint16_t s) +static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s) { - static const char module[] = "ThunderDecodeRow"; - uint8_t* row = buf; - - (void) s; - if (occ % tif->tif_scanlinesize) - { - TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); - return (0); - } - while (occ > 0) { - if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) - return (0); - occ -= tif->tif_scanlinesize; - row += tif->tif_scanlinesize; - } - return (1); + static const char module[] = "ThunderDecodeRow"; + uint8_t *row = buf; + + (void)s; + if (occ % tif->tif_scanlinesize) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); + return (0); + } + while (occ > 0) + { + if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) + return (0); + occ -= tif->tif_scanlinesize; + row += tif->tif_scanlinesize; + } + return (1); } -int -TIFFInitThunderScan(TIFF* tif, int scheme) +int TIFFInitThunderScan(TIFF *tif, int scheme) { - (void) scheme; + (void)scheme; - tif->tif_setupdecode = ThunderSetupDecode; - tif->tif_decoderow = ThunderDecodeRow; - tif->tif_decodestrip = ThunderDecodeRow; - return (1); + tif->tif_setupdecode = ThunderSetupDecode; + tif->tif_decoderow = ThunderDecodeRow; + tif->tif_decodestrip = ThunderDecodeRow; + return (1); } #endif /* THUNDER_SUPPORT */ diff --git a/libtiff/tif_tile.c b/libtiff/tif_tile.c index e9a5b1b9..f07032f7 100644 --- a/libtiff/tif_tile.c +++ b/libtiff/tif_tile.c @@ -2,23 +2,23 @@ * Copyright (c) 1991-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -32,234 +32,230 @@ /* * Compute which tile an (x,y,z,s) value is in. */ -uint32_t -TIFFComputeTile(TIFF* tif, uint32_t x, uint32_t y, uint32_t z, uint16_t s) +uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, + uint16_t s) { - TIFFDirectory *td = &tif->tif_dir; - uint32_t dx = td->td_tilewidth; - uint32_t dy = td->td_tilelength; - uint32_t dz = td->td_tiledepth; - uint32_t tile = 1; + TIFFDirectory *td = &tif->tif_dir; + uint32_t dx = td->td_tilewidth; + uint32_t dy = td->td_tilelength; + uint32_t dz = td->td_tiledepth; + uint32_t tile = 1; - if (td->td_imagedepth == 1) - z = 0; - if (dx == (uint32_t) -1) - dx = td->td_imagewidth; - if (dy == (uint32_t) -1) - dy = td->td_imagelength; - if (dz == (uint32_t) -1) - dz = td->td_imagedepth; - if (dx != 0 && dy != 0 && dz != 0) { - uint32_t xpt = TIFFhowmany_32(td->td_imagewidth, dx); - uint32_t ypt = TIFFhowmany_32(td->td_imagelength, dy); - uint32_t zpt = TIFFhowmany_32(td->td_imagedepth, dz); + if (td->td_imagedepth == 1) + z = 0; + if (dx == (uint32_t)-1) + dx = td->td_imagewidth; + if (dy == (uint32_t)-1) + dy = td->td_imagelength; + if (dz == (uint32_t)-1) + dz = td->td_imagedepth; + if (dx != 0 && dy != 0 && dz != 0) + { + uint32_t xpt = TIFFhowmany_32(td->td_imagewidth, dx); + uint32_t ypt = TIFFhowmany_32(td->td_imagelength, dy); + uint32_t zpt = TIFFhowmany_32(td->td_imagedepth, dz); - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - tile = (xpt*ypt*zpt)*s + - (xpt*ypt)*(z/dz) + - xpt*(y/dy) + - x/dx; - else - tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx; - } - return (tile); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + tile = (xpt * ypt * zpt) * s + (xpt * ypt) * (z / dz) + + xpt * (y / dy) + x / dx; + else + tile = (xpt * ypt) * (z / dz) + xpt * (y / dy) + x / dx; + } + return (tile); } /* * Check an (x,y,z,s) coordinate * against the image bounds. */ -int -TIFFCheckTile(TIFF* tif, uint32_t x, uint32_t y, uint32_t z, uint16_t s) +int TIFFCheckTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, uint16_t s) { - TIFFDirectory *td = &tif->tif_dir; + TIFFDirectory *td = &tif->tif_dir; - if (x >= td->td_imagewidth) { - TIFFErrorExtR(tif, tif->tif_name, - "%lu: Col out of range, max %lu", - (unsigned long) x, - (unsigned long) (td->td_imagewidth - 1)); - return (0); - } - if (y >= td->td_imagelength) { - TIFFErrorExtR(tif, tif->tif_name, - "%lu: Row out of range, max %lu", - (unsigned long) y, - (unsigned long) (td->td_imagelength - 1)); - return (0); - } - if (z >= td->td_imagedepth) { - TIFFErrorExtR(tif, tif->tif_name, - "%lu: Depth out of range, max %lu", - (unsigned long) z, - (unsigned long) (td->td_imagedepth - 1)); - return (0); - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE && - s >= td->td_samplesperpixel) { - TIFFErrorExtR(tif, tif->tif_name, - "%lu: Sample out of range, max %lu", - (unsigned long) s, - (unsigned long) (td->td_samplesperpixel - 1)); - return (0); - } - return (1); + if (x >= td->td_imagewidth) + { + TIFFErrorExtR(tif, tif->tif_name, "%lu: Col out of range, max %lu", + (unsigned long)x, (unsigned long)(td->td_imagewidth - 1)); + return (0); + } + if (y >= td->td_imagelength) + { + TIFFErrorExtR(tif, tif->tif_name, "%lu: Row out of range, max %lu", + (unsigned long)y, + (unsigned long)(td->td_imagelength - 1)); + return (0); + } + if (z >= td->td_imagedepth) + { + TIFFErrorExtR(tif, tif->tif_name, "%lu: Depth out of range, max %lu", + (unsigned long)z, (unsigned long)(td->td_imagedepth - 1)); + return (0); + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE && + s >= td->td_samplesperpixel) + { + TIFFErrorExtR(tif, tif->tif_name, "%lu: Sample out of range, max %lu", + (unsigned long)s, + (unsigned long)(td->td_samplesperpixel - 1)); + return (0); + } + return (1); } /* * Compute how many tiles are in an image. */ -uint32_t -TIFFNumberOfTiles(TIFF* tif) +uint32_t TIFFNumberOfTiles(TIFF *tif) { - TIFFDirectory *td = &tif->tif_dir; - uint32_t dx = td->td_tilewidth; - uint32_t dy = td->td_tilelength; - uint32_t dz = td->td_tiledepth; - uint32_t ntiles; + TIFFDirectory *td = &tif->tif_dir; + uint32_t dx = td->td_tilewidth; + uint32_t dy = td->td_tilelength; + uint32_t dz = td->td_tiledepth; + uint32_t ntiles; - if (dx == (uint32_t) -1) - dx = td->td_imagewidth; - if (dy == (uint32_t) -1) - dy = td->td_imagelength; - if (dz == (uint32_t) -1) - dz = td->td_imagedepth; - ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 : - _TIFFMultiply32(tif, _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx), - TIFFhowmany_32(td->td_imagelength, dy), - "TIFFNumberOfTiles"), - TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles"); - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel, - "TIFFNumberOfTiles"); - return (ntiles); + if (dx == (uint32_t)-1) + dx = td->td_imagewidth; + if (dy == (uint32_t)-1) + dy = td->td_imagelength; + if (dz == (uint32_t)-1) + dz = td->td_imagedepth; + ntiles = + (dx == 0 || dy == 0 || dz == 0) + ? 0 + : _TIFFMultiply32( + tif, + _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx), + TIFFhowmany_32(td->td_imagelength, dy), + "TIFFNumberOfTiles"), + TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles"); + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel, + "TIFFNumberOfTiles"); + return (ntiles); } /* * Compute the # bytes in each row of a tile. */ -uint64_t -TIFFTileRowSize64(TIFF* tif) +uint64_t TIFFTileRowSize64(TIFF *tif) { - static const char module[] = "TIFFTileRowSize64"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t rowsize; - uint64_t tilerowsize; + static const char module[] = "TIFFTileRowSize64"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t rowsize; + uint64_t tilerowsize; - if (td->td_tilelength == 0) - { - TIFFErrorExtR(tif,module,"Tile length is zero"); - return 0; - } - if (td->td_tilewidth == 0) - { - TIFFErrorExtR(tif,module,"Tile width is zero"); - return (0); - } - rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth, - "TIFFTileRowSize"); - if (td->td_planarconfig == PLANARCONFIG_CONTIG) - { - if (td->td_samplesperpixel == 0) - { - TIFFErrorExtR(tif,module,"Samples per pixel is zero"); - return 0; - } - rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel, - "TIFFTileRowSize"); - } - tilerowsize=TIFFhowmany8_64(rowsize); - if (tilerowsize == 0) + if (td->td_tilelength == 0) + { + TIFFErrorExtR(tif, module, "Tile length is zero"); + return 0; + } + if (td->td_tilewidth == 0) + { + TIFFErrorExtR(tif, module, "Tile width is zero"); + return (0); + } + rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth, + "TIFFTileRowSize"); + if (td->td_planarconfig == PLANARCONFIG_CONTIG) + { + if (td->td_samplesperpixel == 0) { - TIFFErrorExtR(tif,module,"Computed tile row size is zero"); - return 0; + TIFFErrorExtR(tif, module, "Samples per pixel is zero"); + return 0; } - return (tilerowsize); + rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel, + "TIFFTileRowSize"); + } + tilerowsize = TIFFhowmany8_64(rowsize); + if (tilerowsize == 0) + { + TIFFErrorExtR(tif, module, "Computed tile row size is zero"); + return 0; + } + return (tilerowsize); } -tmsize_t -TIFFTileRowSize(TIFF* tif) +tmsize_t TIFFTileRowSize(TIFF *tif) { - static const char module[] = "TIFFTileRowSize"; - uint64_t m; - m=TIFFTileRowSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFTileRowSize"; + uint64_t m; + m = TIFFTileRowSize64(tif); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* * Compute the # bytes in a variable length, row-aligned tile. */ -uint64_t -TIFFVTileSize64(TIFF* tif, uint32_t nrows) +uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows) { - static const char module[] = "TIFFVTileSize64"; - TIFFDirectory *td = &tif->tif_dir; - if (td->td_tilelength == 0 || td->td_tilewidth == 0 || - td->td_tiledepth == 0) - return (0); - if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&& - (td->td_photometric==PHOTOMETRIC_YCBCR)&& - (td->td_samplesperpixel==3)&& - (!isUpSampled(tif))) - { - /* - * Packed YCbCr data contain one Cb+Cr for every - * HorizontalSampling*VerticalSampling Y values. - * Must also roundup width and height when calculating - * since images that are not a multiple of the - * horizontal/vertical subsampling area include - * YCbCr data for the extended image. - */ - uint16_t ycbcrsubsampling[2]; - uint16_t samplingblock_samples; - uint32_t samplingblocks_hor; - uint32_t samplingblocks_ver; - uint64_t samplingrow_samples; - uint64_t samplingrow_size; - TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0, - ycbcrsubsampling+1); - if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4) - ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4)) - { - TIFFErrorExtR(tif,module, - "Invalid YCbCr subsampling (%dx%d)", - ycbcrsubsampling[0], - ycbcrsubsampling[1] ); - return 0; - } - samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2; - samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]); - samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]); - samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module); - samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module)); - return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module)); - } - else - return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module)); + static const char module[] = "TIFFVTileSize64"; + TIFFDirectory *td = &tif->tif_dir; + if (td->td_tilelength == 0 || td->td_tilewidth == 0 || + td->td_tiledepth == 0) + return (0); + if ((td->td_planarconfig == PLANARCONFIG_CONTIG) && + (td->td_photometric == PHOTOMETRIC_YCBCR) && + (td->td_samplesperpixel == 3) && (!isUpSampled(tif))) + { + /* + * Packed YCbCr data contain one Cb+Cr for every + * HorizontalSampling*VerticalSampling Y values. + * Must also roundup width and height when calculating + * since images that are not a multiple of the + * horizontal/vertical subsampling area include + * YCbCr data for the extended image. + */ + uint16_t ycbcrsubsampling[2]; + uint16_t samplingblock_samples; + uint32_t samplingblocks_hor; + uint32_t samplingblocks_ver; + uint64_t samplingrow_samples; + uint64_t samplingrow_size; + TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, + ycbcrsubsampling + 0, ycbcrsubsampling + 1); + if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && + ycbcrsubsampling[0] != 4) || + (ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && + ycbcrsubsampling[1] != 4)) + { + TIFFErrorExtR(tif, module, "Invalid YCbCr subsampling (%dx%d)", + ycbcrsubsampling[0], ycbcrsubsampling[1]); + return 0; + } + samplingblock_samples = ycbcrsubsampling[0] * ycbcrsubsampling[1] + 2; + samplingblocks_hor = + TIFFhowmany_32(td->td_tilewidth, ycbcrsubsampling[0]); + samplingblocks_ver = TIFFhowmany_32(nrows, ycbcrsubsampling[1]); + samplingrow_samples = _TIFFMultiply64(tif, samplingblocks_hor, + samplingblock_samples, module); + samplingrow_size = TIFFhowmany8_64(_TIFFMultiply64( + tif, samplingrow_samples, td->td_bitspersample, module)); + return ( + _TIFFMultiply64(tif, samplingrow_size, samplingblocks_ver, module)); + } + else + return (_TIFFMultiply64(tif, nrows, TIFFTileRowSize64(tif), module)); } -tmsize_t -TIFFVTileSize(TIFF* tif, uint32_t nrows) +tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows) { - static const char module[] = "TIFFVTileSize"; - uint64_t m; - m=TIFFVTileSize64(tif,nrows); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFVTileSize"; + uint64_t m; + m = TIFFVTileSize64(tif, nrows); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* * Compute the # bytes in a row-aligned tile. */ -uint64_t -TIFFTileSize64(TIFF* tif) +uint64_t TIFFTileSize64(TIFF *tif) { - return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength)); + return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength)); } -tmsize_t -TIFFTileSize(TIFF* tif) +tmsize_t TIFFTileSize(TIFF *tif) { - static const char module[] = "TIFFTileSize"; - uint64_t m; - m=TIFFTileSize64(tif); - return _TIFFCastUInt64ToSSize(tif, m, module); + static const char module[] = "TIFFTileSize"; + uint64_t m; + m = TIFFTileSize64(tif); + return _TIFFCastUInt64ToSSize(tif, m, module); } /* @@ -268,23 +264,21 @@ TIFFTileSize(TIFF* tif) * request is <1 then we choose a size according * to certain heuristics. */ -void -TIFFDefaultTileSize(TIFF* tif, uint32_t* tw, uint32_t* th) +void TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) { - (*tif->tif_deftilesize)(tif, tw, th); + (*tif->tif_deftilesize)(tif, tw, th); } -void -_TIFFDefaultTileSize(TIFF* tif, uint32_t* tw, uint32_t* th) +void _TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th) { - (void) tif; - if (*(int32_t*) tw < 1) - *tw = 256; - if (*(int32_t*) th < 1) - *th = 256; - /* roundup to a multiple of 16 per the spec */ - if (*tw & 0xf) - *tw = TIFFroundup_32(*tw, 16); - if (*th & 0xf) - *th = TIFFroundup_32(*th, 16); + (void)tif; + if (*(int32_t *)tw < 1) + *tw = 256; + if (*(int32_t *)th < 1) + *th = 256; + /* roundup to a multiple of 16 per the spec */ + if (*tw & 0xf) + *tw = TIFFroundup_32(*tw, 16); + if (*th & 0xf) + *th = TIFFroundup_32(*th, 16); } diff --git a/libtiff/tif_unix.c b/libtiff/tif_unix.c index 8af77681..34dd53b9 100644 --- a/libtiff/tif_unix.c +++ b/libtiff/tif_unix.c @@ -30,7 +30,7 @@ #include "tif_config.h" #ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> +#include <sys/types.h> #endif #include <errno.h> @@ -40,188 +40,175 @@ #include <sys/stat.h> #ifdef HAVE_UNISTD_H -# include <unistd.h> +#include <unistd.h> #endif #ifdef HAVE_FCNTL_H -# include <fcntl.h> +#include <fcntl.h> #endif #ifdef HAVE_IO_H -# include <io.h> +#include <io.h> #endif #include "tiffiop.h" - #define TIFF_IO_MAX 2147483647U - typedef union fd_as_handle_union { - int fd; - thandle_t h; + int fd; + thandle_t h; } fd_as_handle_union_t; -static tmsize_t -_tiffReadProc(thandle_t fd, void* buf, tmsize_t size) +static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size) { - fd_as_handle_union_t fdh; - const size_t bytes_total = (size_t) size; - size_t bytes_read; - tmsize_t count = -1; - if ((tmsize_t) bytes_total != size) - { - errno=EINVAL; - return (tmsize_t) -1; - } - fdh.h = fd; - for (bytes_read=0; bytes_read < bytes_total; bytes_read+=count) - { - char *buf_offset = (char *) buf+bytes_read; - size_t io_size = bytes_total-bytes_read; - if (io_size > TIFF_IO_MAX) - io_size = TIFF_IO_MAX; - count=read(fdh.fd, buf_offset, (TIFFIOSize_t) io_size); - if (count <= 0) - break; - } - if (count < 0) - return (tmsize_t)-1; - return (tmsize_t) bytes_read; + fd_as_handle_union_t fdh; + const size_t bytes_total = (size_t)size; + size_t bytes_read; + tmsize_t count = -1; + if ((tmsize_t)bytes_total != size) + { + errno = EINVAL; + return (tmsize_t)-1; + } + fdh.h = fd; + for (bytes_read = 0; bytes_read < bytes_total; bytes_read += count) + { + char *buf_offset = (char *)buf + bytes_read; + size_t io_size = bytes_total - bytes_read; + if (io_size > TIFF_IO_MAX) + io_size = TIFF_IO_MAX; + count = read(fdh.fd, buf_offset, (TIFFIOSize_t)io_size); + if (count <= 0) + break; + } + if (count < 0) + return (tmsize_t)-1; + return (tmsize_t)bytes_read; } -static tmsize_t -_tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) +static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size) { - fd_as_handle_union_t fdh; - const size_t bytes_total = (size_t) size; - size_t bytes_written; - tmsize_t count = -1; - if ((tmsize_t) bytes_total != size) - { - errno=EINVAL; - return (tmsize_t) -1; - } - fdh.h = fd; - for (bytes_written=0; bytes_written < bytes_total; bytes_written+=count) - { - const char *buf_offset = (char *) buf+bytes_written; - size_t io_size = bytes_total-bytes_written; - if (io_size > TIFF_IO_MAX) - io_size = TIFF_IO_MAX; - count=write(fdh.fd, buf_offset, (TIFFIOSize_t) io_size); - if (count <= 0) - break; - } - if (count < 0) - return (tmsize_t)-1; - return (tmsize_t) bytes_written; - /* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */ + fd_as_handle_union_t fdh; + const size_t bytes_total = (size_t)size; + size_t bytes_written; + tmsize_t count = -1; + if ((tmsize_t)bytes_total != size) + { + errno = EINVAL; + return (tmsize_t)-1; + } + fdh.h = fd; + for (bytes_written = 0; bytes_written < bytes_total; bytes_written += count) + { + const char *buf_offset = (char *)buf + bytes_written; + size_t io_size = bytes_total - bytes_written; + if (io_size > TIFF_IO_MAX) + io_size = TIFF_IO_MAX; + count = write(fdh.fd, buf_offset, (TIFFIOSize_t)io_size); + if (count <= 0) + break; + } + if (count < 0) + return (tmsize_t)-1; + return (tmsize_t)bytes_written; + /* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */ } -static uint64_t -_tiffSeekProc(thandle_t fd, uint64_t off, int whence) +static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence) { - fd_as_handle_union_t fdh; - _TIFF_off_t off_io = (_TIFF_off_t) off; - if ((uint64_t) off_io != off) - { - errno=EINVAL; - return (uint64_t) -1; /* this is really gross */ - } - fdh.h = fd; - return((uint64_t)_TIFF_lseek_f(fdh.fd, off_io, whence)); + fd_as_handle_union_t fdh; + _TIFF_off_t off_io = (_TIFF_off_t)off; + if ((uint64_t)off_io != off) + { + errno = EINVAL; + return (uint64_t)-1; /* this is really gross */ + } + fdh.h = fd; + return ((uint64_t)_TIFF_lseek_f(fdh.fd, off_io, whence)); } -static int -_tiffCloseProc(thandle_t fd) +static int _tiffCloseProc(thandle_t fd) { - fd_as_handle_union_t fdh; - fdh.h = fd; - return(close(fdh.fd)); + fd_as_handle_union_t fdh; + fdh.h = fd; + return (close(fdh.fd)); } -static uint64_t -_tiffSizeProc(thandle_t fd) +static uint64_t _tiffSizeProc(thandle_t fd) { - _TIFF_stat_s sb; - fd_as_handle_union_t fdh; - fdh.h = fd; - if (_TIFF_fstat_f(fdh.fd,&sb)<0) - return(0); - else - return((uint64_t)sb.st_size); + _TIFF_stat_s sb; + fd_as_handle_union_t fdh; + fdh.h = fd; + if (_TIFF_fstat_f(fdh.fd, &sb) < 0) + return (0); + else + return ((uint64_t)sb.st_size); } #ifdef HAVE_MMAP #include <sys/mman.h> -static int -_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) +static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) { - uint64_t size64 = _tiffSizeProc(fd); - tmsize_t sizem = (tmsize_t)size64; - if (size64 && (uint64_t)sizem == size64) { - fd_as_handle_union_t fdh; - fdh.h = fd; - *pbase = (void*) - mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0); - if (*pbase != (void*) -1) { - *psize = (tmsize_t)sizem; - return (1); - } - } - return (0); + uint64_t size64 = _tiffSizeProc(fd); + tmsize_t sizem = (tmsize_t)size64; + if (size64 && (uint64_t)sizem == size64) + { + fd_as_handle_union_t fdh; + fdh.h = fd; + *pbase = + (void *)mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0); + if (*pbase != (void *)-1) + { + *psize = (tmsize_t)sizem; + return (1); + } + } + return (0); } -static void -_tiffUnmapProc(thandle_t fd, void* base, toff_t size) +static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size) { - (void) fd; - (void) munmap(base, (off_t) size); + (void)fd; + (void)munmap(base, (off_t)size); } -#else /* !HAVE_MMAP */ -static int -_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) +#else /* !HAVE_MMAP */ +static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) { - (void) fd; (void) pbase; (void) psize; - return (0); + (void)fd; + (void)pbase; + (void)psize; + return (0); } -static void -_tiffUnmapProc(thandle_t fd, void* base, toff_t size) +static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size) { - (void) fd; (void) base; (void) size; + (void)fd; + (void)base; + (void)size; } #endif /* !HAVE_MMAP */ /* * Open a TIFF file descriptor for read/writing. */ -TIFF* -TIFFFdOpen(int fd, const char* name, const char* mode) +TIFF *TIFFFdOpen(int fd, const char *name, const char *mode) { return TIFFFdOpenExt(fd, name, mode, NULL); } -TIFF* -TIFFFdOpenExt(int fd, const char* name, const char* mode, TIFFOpenOptions* opts) +TIFF *TIFFFdOpenExt(int fd, const char *name, const char *mode, + TIFFOpenOptions *opts) { - TIFF* tif; + TIFF *tif; fd_as_handle_union_t fdh; fdh.fd = fd; - tif = TIFFClientOpenExt(name, mode, - fdh.h, - _tiffReadProc, - _tiffWriteProc, - _tiffSeekProc, - _tiffCloseProc, - _tiffSizeProc, - _tiffMapProc, - _tiffUnmapProc, - opts); + tif = TIFFClientOpenExt(name, mode, fdh.h, _tiffReadProc, _tiffWriteProc, + _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, + _tiffMapProc, _tiffUnmapProc, opts); if (tif) tif->tif_fd = fd; return (tif); @@ -230,42 +217,45 @@ TIFFFdOpenExt(int fd, const char* name, const char* mode, TIFFOpenOptions* opts) /* * Open a TIFF file for read/writing. */ -TIFF* -TIFFOpen(const char* name, const char* mode) +TIFF *TIFFOpen(const char *name, const char *mode) { return TIFFOpenExt(name, mode, NULL); } -TIFF* -TIFFOpenExt(const char* name, const char* mode, TIFFOpenOptions* opts) +TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts) { - static const char module[] = "TIFFOpen"; - int m, fd; - TIFF* tif; + static const char module[] = "TIFFOpen"; + int m, fd; + TIFF *tif; - m = _TIFFgetMode(opts, NULL, mode, module); - if (m == -1) - return ((TIFF*)0); + m = _TIFFgetMode(opts, NULL, mode, module); + if (m == -1) + return ((TIFF *)0); /* for cygwin and mingw */ #ifdef O_BINARY - m |= O_BINARY; + m |= O_BINARY; #endif - fd = open(name, m, 0666); - if (fd < 0) { - if (errno > 0 && strerror(errno) != NULL ) { - _TIFFErrorEarly(opts, NULL, module, "%s: %s", name, strerror(errno) ); - } else { - _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name); - } - return ((TIFF *)0); - } - - tif = TIFFFdOpenExt((int)fd, name, mode, opts); - if(!tif) - close(fd); - return tif; + fd = open(name, m, 0666); + if (fd < 0) + { + if (errno > 0 && strerror(errno) != NULL) + { + _TIFFErrorEarly(opts, NULL, module, "%s: %s", name, + strerror(errno)); + } + else + { + _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name); + } + return ((TIFF *)0); + } + + tif = TIFFFdOpenExt((int)fd, name, mode, opts); + if (!tif) + close(fd); + return tif; } #ifdef __WIN32__ @@ -273,124 +263,108 @@ TIFFOpenExt(const char* name, const char* mode, TIFFOpenOptions* opts) /* * Open a TIFF file with a Unicode filename, for read/writing. */ -TIFF* -TIFFOpenW(const wchar_t* name, const char* mode) +TIFF *TIFFOpenW(const wchar_t *name, const char *mode) { return TIFFOpenWExt(name, mode, NULL); } -TIFF* -TIFFOpenWExt(const wchar_t* name, const char* mode, TIFFOpenOptions* opts) +TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts) { - static const char module[] = "TIFFOpenW"; - int m, fd; - int mbsize; - char *mbname; - TIFF* tif; + static const char module[] = "TIFFOpenW"; + int m, fd; + int mbsize; + char *mbname; + TIFF *tif; - m = _TIFFgetMode(opts, NULL, mode, module); - if (m == -1) - return ((TIFF*)0); + m = _TIFFgetMode(opts, NULL, mode, module); + if (m == -1) + return ((TIFF *)0); /* for cygwin and mingw */ #ifdef O_BINARY - m |= O_BINARY; + m |= O_BINARY; #endif - fd = _wopen(name, m, 0666); - if (fd < 0) { - _TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name); - return ((TIFF *)0); - } - - mbname = NULL; - mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); - if (mbsize > 0) { - mbname = _TIFFmalloc(mbsize); - if (!mbname) { - _TIFFErrorEarly(opts, NULL, module, - "Can't allocate space for filename conversion buffer"); - return ((TIFF*)0); - } - - WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, - NULL, NULL); - } - - tif = TIFFFdOpenExt((int)fd, (mbname != NULL) ? mbname : "<unknown>", - mode, opts); - - _TIFFfree(mbname); - - if(!tif) - close(fd); - return tif; + fd = _wopen(name, m, 0666); + if (fd < 0) + { + _TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name); + return ((TIFF *)0); + } + + mbname = NULL; + mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); + if (mbsize > 0) + { + mbname = _TIFFmalloc(mbsize); + if (!mbname) + { + _TIFFErrorEarly( + opts, NULL, module, + "Can't allocate space for filename conversion buffer"); + return ((TIFF *)0); + } + + WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL); + } + + tif = TIFFFdOpenExt((int)fd, (mbname != NULL) ? mbname : "<unknown>", mode, + opts); + + _TIFFfree(mbname); + + if (!tif) + close(fd); + return tif; } #endif -void* -_TIFFmalloc(tmsize_t s) +void *_TIFFmalloc(tmsize_t s) { - if (s == 0) - return ((void *) NULL); + if (s == 0) + return ((void *)NULL); - return (malloc((size_t) s)); + return (malloc((size_t)s)); } -void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) +void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz) { - if( nmemb == 0 || siz == 0 ) - return ((void *) NULL); + if (nmemb == 0 || siz == 0) + return ((void *)NULL); - return calloc((size_t) nmemb, (size_t)siz); + return calloc((size_t)nmemb, (size_t)siz); } -void -_TIFFfree(void* p) -{ - free(p); -} +void _TIFFfree(void *p) { free(p); } -void* -_TIFFrealloc(void* p, tmsize_t s) -{ - return (realloc(p, (size_t) s)); -} +void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); } -void -_TIFFmemset(void* p, int v, tmsize_t c) -{ - memset(p, v, (size_t) c); -} +void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); } -void -_TIFFmemcpy(void* d, const void* s, tmsize_t c) +void _TIFFmemcpy(void *d, const void *s, tmsize_t c) { - memcpy(d, s, (size_t) c); + memcpy(d, s, (size_t)c); } -int -_TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) +int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c) { - return (memcmp(p1, p2, (size_t) c)); + return (memcmp(p1, p2, (size_t)c)); } -static void -unixWarningHandler(const char* module, const char* fmt, va_list ap) +static void unixWarningHandler(const char *module, const char *fmt, va_list ap) { - if (module != NULL) - fprintf(stderr, "%s: ", module); - fprintf(stderr, "Warning, "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); } TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler; -static void -unixErrorHandler(const char* module, const char* fmt, va_list ap) +static void unixErrorHandler(const char *module, const char *fmt, va_list ap) { - if (module != NULL) - fprintf(stderr, "%s: ", module); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); } TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler; diff --git a/libtiff/tif_version.c b/libtiff/tif_version.c index 48e755c3..0b6c9bc0 100644 --- a/libtiff/tif_version.c +++ b/libtiff/tif_version.c @@ -2,31 +2,27 @@ * Copyright (c) 1992-1997 Sam Leffler * Copyright (c) 1992-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #include "tiffiop.h" static const char TIFFVersion[] = TIFFLIB_VERSION_STR; -const char* -TIFFGetVersion(void) -{ - return (TIFFVersion); -} +const char *TIFFGetVersion(void) { return (TIFFVersion); } diff --git a/libtiff/tif_warning.c b/libtiff/tif_warning.c index 927a216d..5468de55 100644 --- a/libtiff/tif_warning.c +++ b/libtiff/tif_warning.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -29,71 +29,77 @@ TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL; -TIFFErrorHandler -TIFFSetWarningHandler(TIFFErrorHandler handler) +TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler handler) { - TIFFErrorHandler prev = _TIFFwarningHandler; - _TIFFwarningHandler = handler; - return (prev); + TIFFErrorHandler prev = _TIFFwarningHandler; + _TIFFwarningHandler = handler; + return (prev); } -TIFFErrorHandlerExt -TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler) +TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler) { - TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt; - _TIFFwarningHandlerExt = handler; - return (prev); + TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt; + _TIFFwarningHandlerExt = handler; + return (prev); } -void -TIFFWarning(const char* module, const char* fmt, ...) +void TIFFWarning(const char *module, const char *fmt, ...) { - va_list ap; - if (_TIFFwarningHandler) { - va_start(ap, fmt); - (*_TIFFwarningHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFwarningHandlerExt) { - va_start(ap, fmt); - (*_TIFFwarningHandlerExt)(0, module, fmt, ap); - va_end(ap); - } + va_list ap; + if (_TIFFwarningHandler) + { + va_start(ap, fmt); + (*_TIFFwarningHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFwarningHandlerExt) + { + va_start(ap, fmt); + (*_TIFFwarningHandlerExt)(0, module, fmt, ap); + va_end(ap); + } } -void -TIFFWarningExt(thandle_t fd, const char* module, const char* fmt, ...) +void TIFFWarningExt(thandle_t fd, const char *module, const char *fmt, ...) { - va_list ap; - if (_TIFFwarningHandler) { - va_start(ap, fmt); - (*_TIFFwarningHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFwarningHandlerExt) { - va_start(ap, fmt); - (*_TIFFwarningHandlerExt)(fd, module, fmt, ap); - va_end(ap); - } + va_list ap; + if (_TIFFwarningHandler) + { + va_start(ap, fmt); + (*_TIFFwarningHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFwarningHandlerExt) + { + va_start(ap, fmt); + (*_TIFFwarningHandlerExt)(fd, module, fmt, ap); + va_end(ap); + } } -void TIFFWarningExtR(TIFF* tif, const char* module, const char* fmt, ...) +void TIFFWarningExtR(TIFF *tif, const char *module, const char *fmt, ...) { - va_list ap; - if (tif && tif->tif_warnhandler) { - va_start(ap, fmt); - int stop = (*tif->tif_warnhandler)(tif, tif->tif_warnhandler_user_data, module, fmt, ap); - va_end(ap); - if (stop) return; - } - if (_TIFFwarningHandler) { - va_start(ap, fmt); - (*_TIFFwarningHandler)(module, fmt, ap); - va_end(ap); - } - if (_TIFFwarningHandlerExt) { - va_start(ap, fmt); - (*_TIFFwarningHandlerExt)(tif ? tif->tif_clientdata : 0, module, fmt, ap); - va_end(ap); - } + va_list ap; + if (tif && tif->tif_warnhandler) + { + va_start(ap, fmt); + int stop = (*tif->tif_warnhandler)(tif, tif->tif_warnhandler_user_data, + module, fmt, ap); + va_end(ap); + if (stop) + return; + } + if (_TIFFwarningHandler) + { + va_start(ap, fmt); + (*_TIFFwarningHandler)(module, fmt, ap); + va_end(ap); + } + if (_TIFFwarningHandlerExt) + { + va_start(ap, fmt); + (*_TIFFwarningHandlerExt)(tif ? tif->tif_clientdata : 0, module, fmt, + ap); + va_end(ap); + } } diff --git a/libtiff/tif_webp.c b/libtiff/tif_webp.c index 14b7f96e..07db7cce 100644 --- a/libtiff/tif_webp.c +++ b/libtiff/tif_webp.c @@ -1,26 +1,26 @@ /* -* Copyright (c) 2018, Mapbox -* Author: <norman.barker at mapbox.com> -* -* Permission to use, copy, modify, distribute, and sell this software and -* its documentation for any purpose is hereby granted without fee, provided -* that (i) the above copyright notices and this permission notice appear in -* all copies of the software and related documentation, and (ii) the names of -* Sam Leffler and Silicon Graphics may not be used in any advertising or -* publicity relating to the software without the specific, prior written -* permission of Sam Leffler and Silicon Graphics. -* -* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -* -* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR -* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, -* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF -* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -* OF THIS SOFTWARE. -*/ + * Copyright (c) 2018, Mapbox + * Author: <norman.barker at mapbox.com> + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ #include "tiffiop.h" #ifdef WEBP_SUPPORT @@ -34,8 +34,8 @@ #include "webp/decode.h" #include "webp/encode.h" -#include <stdio.h> #include <stdbool.h> +#include <stdio.h> #define LSTATE_INIT_DECODE 0x01 #define LSTATE_INIT_ENCODE 0x02 @@ -43,727 +43,758 @@ * State block for each open TIFF * file using WEBP compression/decompression. */ -typedef struct { - uint16_t nSamples; /* number of samples per pixel */ +typedef struct +{ + uint16_t nSamples; /* number of samples per pixel */ - int lossless; /* lossy/lossless compression */ - int quality_level; /* compression level */ - WebPPicture sPicture; /* WebP Picture */ - WebPConfig sEncoderConfig; /* WebP encoder config */ - uint8_t* pBuffer; /* buffer to hold raw data on encoding */ - unsigned int buffer_offset; /* current offset into the buffer */ - unsigned int buffer_size; + int lossless; /* lossy/lossless compression */ + int quality_level; /* compression level */ + WebPPicture sPicture; /* WebP Picture */ + WebPConfig sEncoderConfig; /* WebP encoder config */ + uint8_t *pBuffer; /* buffer to hold raw data on encoding */ + unsigned int buffer_offset; /* current offset into the buffer */ + unsigned int buffer_size; - WebPIDecoder* psDecoder; /* WebPIDecoder */ - WebPDecBuffer sDecBuffer; /* Decoder buffer */ - int last_y; /* Last row decoded */ + WebPIDecoder *psDecoder; /* WebPIDecoder */ + WebPDecBuffer sDecBuffer; /* Decoder buffer */ + int last_y; /* Last row decoded */ - int state; /* state flags */ + int state; /* state flags */ - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ } WebPState; -#define LState(tif) ((WebPState*) (tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) +#define LState(tif) ((WebPState *)(tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) -static int TWebPEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s); -static int TWebPDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s); +static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -static -int TWebPDatasetWriter(const uint8_t* data, size_t data_size, - const WebPPicture* const picture) +static int TWebPDatasetWriter(const uint8_t *data, size_t data_size, + const WebPPicture *const picture) { - static const char module[] = "TWebPDatasetWriter"; - TIFF* tif = (TIFF*)(picture->custom_ptr); - - if ( (tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize ) { - TIFFErrorExtR(tif, module, - "Buffer too small by %"TIFF_SIZE_FORMAT" bytes.", - (size_t) (tif->tif_rawcc + data_size - tif->tif_rawdatasize)); - return 0; - } else { - _TIFFmemcpy(tif->tif_rawcp, data, data_size); - tif->tif_rawcc += data_size; - tif->tif_rawcp += data_size; - return 1; - } + static const char module[] = "TWebPDatasetWriter"; + TIFF *tif = (TIFF *)(picture->custom_ptr); + + if ((tif->tif_rawcc + (tmsize_t)data_size) > tif->tif_rawdatasize) + { + TIFFErrorExtR( + tif, module, "Buffer too small by %" TIFF_SIZE_FORMAT " bytes.", + (size_t)(tif->tif_rawcc + data_size - tif->tif_rawdatasize)); + return 0; + } + else + { + _TIFFmemcpy(tif->tif_rawcp, data, data_size); + tif->tif_rawcc += data_size; + tif->tif_rawcp += data_size; + return 1; + } } /* * Encode a chunk of pixels. */ -static int -TWebPEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int TWebPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "TWebPEncode"; - WebPState *sp = EncoderState(tif); - (void) s; + static const char module[] = "TWebPEncode"; + WebPState *sp = EncoderState(tif); + (void)s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); - if((uint64_t)sp->buffer_offset + - (uint64_t)cc > sp->buffer_size ) - { - TIFFErrorExtR(tif, module, - "Too many bytes to be written"); - return 0; - } - - memcpy(sp->pBuffer + sp->buffer_offset, - bp, cc); - sp->buffer_offset += (unsigned)cc; + if ((uint64_t)sp->buffer_offset + (uint64_t)cc > sp->buffer_size) + { + TIFFErrorExtR(tif, module, "Too many bytes to be written"); + return 0; + } - return 1; + memcpy(sp->pBuffer + sp->buffer_offset, bp, cc); + sp->buffer_offset += (unsigned)cc; + return 1; } -static int -TWebPDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) +static int TWebPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "WebPDecode"; - VP8StatusCode status = VP8_STATUS_OK; - WebPState *sp = DecoderState(tif); - uint32_t segment_width, segment_height; - bool decode_whole_strile = false; - - (void) s; - - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); - - if( sp->psDecoder == NULL ) - { - TIFFDirectory* td = &tif->tif_dir; - uint32_t buffer_size; + static const char module[] = "WebPDecode"; + VP8StatusCode status = VP8_STATUS_OK; + WebPState *sp = DecoderState(tif); + uint32_t segment_width, segment_height; + bool decode_whole_strile = false; + + (void)s; + + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); + + if (sp->psDecoder == NULL) + { + TIFFDirectory *td = &tif->tif_dir; + uint32_t buffer_size; + + if (isTiled(tif)) + { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + } + else + { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + } + + buffer_size = segment_width * segment_height * sp->nSamples; + if (occ == (tmsize_t)buffer_size) + { + /* If decoding the whole strip/tile, we can directly use the */ + /* output buffer */ + decode_whole_strile = true; + } + else if (sp->pBuffer == NULL || buffer_size > sp->buffer_size) + { + if (sp->pBuffer != NULL) + { + _TIFFfreeExt(tif, sp->pBuffer); + sp->pBuffer = NULL; + } + + sp->pBuffer = _TIFFmallocExt(tif, buffer_size); + if (!sp->pBuffer) + { + TIFFErrorExtR(tif, module, "Cannot allocate buffer"); + return 0; + } + sp->buffer_size = buffer_size; + } + + sp->last_y = 0; + + WebPInitDecBuffer(&sp->sDecBuffer); + + sp->sDecBuffer.is_external_memory = 1; + sp->sDecBuffer.width = segment_width; + sp->sDecBuffer.height = segment_height; + sp->sDecBuffer.u.RGBA.rgba = decode_whole_strile ? op : sp->pBuffer; + sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples; + sp->sDecBuffer.u.RGBA.size = buffer_size; + + if (sp->nSamples > 3) + { + sp->sDecBuffer.colorspace = MODE_RGBA; + } + else + { + sp->sDecBuffer.colorspace = MODE_RGB; + } + + sp->psDecoder = WebPINewDecoder(&sp->sDecBuffer); + + if (sp->psDecoder == NULL) + { + TIFFErrorExtR(tif, module, "Unable to allocate WebP decoder."); + return 0; + } + } - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - } - - buffer_size = segment_width * segment_height * sp->nSamples; - if( occ == (tmsize_t)buffer_size ) - { - /* If decoding the whole strip/tile, we can directly use the */ - /* output buffer */ - decode_whole_strile = true; - } - else if( sp->pBuffer == NULL || buffer_size > sp->buffer_size ) - { - if (sp->pBuffer != NULL) { - _TIFFfreeExt(tif, sp->pBuffer); - sp->pBuffer = NULL; - } - - sp->pBuffer = _TIFFmallocExt(tif, buffer_size); - if( !sp->pBuffer) { - TIFFErrorExtR(tif, module, "Cannot allocate buffer"); - return 0; - } - sp->buffer_size = buffer_size; - } - - sp->last_y = 0; - - WebPInitDecBuffer(&sp->sDecBuffer); - - sp->sDecBuffer.is_external_memory = 1; - sp->sDecBuffer.width = segment_width; - sp->sDecBuffer.height = segment_height; - sp->sDecBuffer.u.RGBA.rgba = decode_whole_strile ? op : sp->pBuffer; - sp->sDecBuffer.u.RGBA.stride = segment_width * sp->nSamples; - sp->sDecBuffer.u.RGBA.size = buffer_size; - - if (sp->nSamples > 3) { - sp->sDecBuffer.colorspace = MODE_RGBA; - } else { - sp->sDecBuffer.colorspace = MODE_RGB; - } - - sp->psDecoder = WebPINewDecoder(&sp->sDecBuffer); - - if (sp->psDecoder == NULL) { - TIFFErrorExtR(tif, module, - "Unable to allocate WebP decoder."); + if (occ % sp->sDecBuffer.u.RGBA.stride) + { + TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read"); return 0; - } - } - - if (occ % sp->sDecBuffer.u.RGBA.stride) - { - TIFFErrorExtR(tif, module, - "Fractional scanlines cannot be read"); - return 0; - } - - status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc); + } - if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { - if (status == VP8_STATUS_INVALID_PARAM) { - TIFFErrorExtR(tif, module, - "Invalid parameter used."); - } else if (status == VP8_STATUS_OUT_OF_MEMORY) { - TIFFErrorExtR(tif, module, - "Out of memory."); - } else { - TIFFErrorExtR(tif, module, - "Unrecognized error."); + status = WebPIAppend(sp->psDecoder, tif->tif_rawcp, tif->tif_rawcc); + + if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) + { + if (status == VP8_STATUS_INVALID_PARAM) + { + TIFFErrorExtR(tif, module, "Invalid parameter used."); + } + else if (status == VP8_STATUS_OUT_OF_MEMORY) + { + TIFFErrorExtR(tif, module, "Out of memory."); + } + else + { + TIFFErrorExtR(tif, module, "Unrecognized error."); + } + return 0; + } + else + { + int current_y, stride; + uint8_t *buf; + + /* Returns the RGB/A image decoded so far */ + buf = WebPIDecGetRGB(sp->psDecoder, ¤t_y, NULL, NULL, &stride); + + if ((buf != NULL) && + (occ <= (tmsize_t)stride * (current_y - sp->last_y))) + { + const int numberOfExpectedLines = + (int)(occ / sp->sDecBuffer.u.RGBA.stride); + if (decode_whole_strile) + { + if (current_y != numberOfExpectedLines) + { + TIFFErrorExtR(tif, module, + "Unable to decode WebP data: less lines than " + "expected."); + return 0; + } + } + else + { + memcpy(op, buf + (sp->last_y * stride), occ); + } + + tif->tif_rawcp += tif->tif_rawcc; + tif->tif_rawcc = 0; + sp->last_y += numberOfExpectedLines; + + if (decode_whole_strile) + { + /* We can now free the decoder as we're completely done */ + if (sp->psDecoder != NULL) + { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + } + } + return 1; + } + else + { + TIFFErrorExtR(tif, module, "Unable to decode WebP data."); + return 0; + } } - return 0; - } else { - int current_y, stride; - uint8_t* buf; - - /* Returns the RGB/A image decoded so far */ - buf = WebPIDecGetRGB(sp->psDecoder, ¤t_y, NULL, NULL, &stride); - - if ((buf != NULL) && - (occ <= (tmsize_t)stride * (current_y - sp->last_y))) { - const int numberOfExpectedLines = (int)(occ / sp->sDecBuffer.u.RGBA.stride); - if( decode_whole_strile ) - { - if( current_y != numberOfExpectedLines ) - { - TIFFErrorExtR(tif, module, - "Unable to decode WebP data: less lines than expected."); - return 0; - } - } - else - { - memcpy(op, - buf + (sp->last_y * stride), - occ); - } - - tif->tif_rawcp += tif->tif_rawcc; - tif->tif_rawcc = 0; - sp->last_y += numberOfExpectedLines; - - if( decode_whole_strile ) - { - /* We can now free the decoder as we're completely done */ - if (sp->psDecoder != NULL) - { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - } - } - return 1; - } else { - TIFFErrorExtR(tif, module, "Unable to decode WebP data."); - return 0; - } - } } -static int -TWebPFixupTags(TIFF* tif) +static int TWebPFixupTags(TIFF *tif) { - (void) tif; - if (tif->tif_dir.td_planarconfig != PLANARCONFIG_CONTIG) { - static const char module[] = "TWebPFixupTags"; - TIFFErrorExtR(tif, module, - "TIFF WEBP requires data to be stored contiguously in RGB e.g. RGBRGBRGB " + (void)tif; + if (tif->tif_dir.td_planarconfig != PLANARCONFIG_CONTIG) + { + static const char module[] = "TWebPFixupTags"; + TIFFErrorExtR(tif, module, + "TIFF WEBP requires data to be stored contiguously in " + "RGB e.g. RGBRGBRGB " #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - "or RGBARGBARGBA" + "or RGBARGBARGBA" #endif - ); - return 0; - } - return 1; + ); + return 0; + } + return 1; } -static int -TWebPSetupDecode(TIFF* tif) +static int TWebPSetupDecode(TIFF *tif) { - static const char module[] = "WebPSetupDecode"; - uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample; - uint16_t sampleFormat = tif->tif_dir.td_sampleformat; + static const char module[] = "WebPSetupDecode"; + uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample; + uint16_t sampleFormat = tif->tif_dir.td_sampleformat; - WebPState* sp = DecoderState(tif); - assert(sp != NULL); + WebPState *sp = DecoderState(tif); + assert(sp != NULL); - sp->nSamples = tif->tif_dir.td_samplesperpixel; + sp->nSamples = tif->tif_dir.td_samplesperpixel; - /* check band count */ - if ( sp->nSamples != 3 + /* check band count */ + if (sp->nSamples != 3 #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - && sp->nSamples != 4 + && sp->nSamples != 4 #endif - ) - { - TIFFErrorExtR(tif, module, - "WEBP driver doesn't support %d bands. Must be 3 (RGB) " - #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - "or 4 (RGBA) " - #endif - "bands.", - sp->nSamples ); - return 0; - } + ) + { + TIFFErrorExtR(tif, module, + "WEBP driver doesn't support %d bands. Must be 3 (RGB) " +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + "or 4 (RGBA) " +#endif + "bands.", + sp->nSamples); + return 0; + } - /* check bits per sample and data type */ - if ((nBitsPerSample != 8) && (sampleFormat != 1)) { - TIFFErrorExtR(tif, module, - "WEBP driver requires 8 bit unsigned data"); - return 0; - } + /* check bits per sample and data type */ + if ((nBitsPerSample != 8) && (sampleFormat != 1)) + { + TIFFErrorExtR(tif, module, "WEBP driver requires 8 bit unsigned data"); + return 0; + } - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) { - WebPPictureFree(&sp->sPicture); - if (sp->pBuffer != NULL) { - _TIFFfreeExt(tif, sp->pBuffer); - sp->pBuffer = NULL; - } - sp->buffer_offset = 0; - sp->state = 0; - } + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) + { + WebPPictureFree(&sp->sPicture); + if (sp->pBuffer != NULL) + { + _TIFFfreeExt(tif, sp->pBuffer); + sp->pBuffer = NULL; + } + sp->buffer_offset = 0; + sp->state = 0; + } - sp->state |= LSTATE_INIT_DECODE; + sp->state |= LSTATE_INIT_DECODE; - return 1; + return 1; } /* -* Setup state for decoding a strip. -*/ -static int -TWebPPreDecode(TIFF* tif, uint16_t s) + * Setup state for decoding a strip. + */ +static int TWebPPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "TWebPPreDecode"; - uint32_t segment_width, segment_height; - WebPState* sp = DecoderState(tif); - TIFFDirectory* td = &tif->tif_dir; - (void) s; - assert(sp != NULL); - - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - } - - if( segment_width > 16383 || segment_height > 16383 ) { - TIFFErrorExtR(tif, module, - "WEBP maximum image dimensions are 16383 x 16383."); - return 0; - } - - if( (sp->state & LSTATE_INIT_DECODE) == 0 ) - tif->tif_setupdecode(tif); - - if (sp->psDecoder != NULL) { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - } + static const char module[] = "TWebPPreDecode"; + uint32_t segment_width, segment_height; + WebPState *sp = DecoderState(tif); + TIFFDirectory *td = &tif->tif_dir; + (void)s; + assert(sp != NULL); + + if (isTiled(tif)) + { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + } + else + { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + } + + if (segment_width > 16383 || segment_height > 16383) + { + TIFFErrorExtR(tif, module, + "WEBP maximum image dimensions are 16383 x 16383."); + return 0; + } + + if ((sp->state & LSTATE_INIT_DECODE) == 0) + tif->tif_setupdecode(tif); - return 1; + if (sp->psDecoder != NULL) + { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + } + + return 1; } -static int -TWebPSetupEncode(TIFF* tif) +static int TWebPSetupEncode(TIFF *tif) { - static const char module[] = "WebPSetupEncode"; - uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample; - uint16_t sampleFormat = tif->tif_dir.td_sampleformat; + static const char module[] = "WebPSetupEncode"; + uint16_t nBitsPerSample = tif->tif_dir.td_bitspersample; + uint16_t sampleFormat = tif->tif_dir.td_sampleformat; - WebPState* sp = EncoderState(tif); - assert(sp != NULL); + WebPState *sp = EncoderState(tif); + assert(sp != NULL); - sp->nSamples = tif->tif_dir.td_samplesperpixel; + sp->nSamples = tif->tif_dir.td_samplesperpixel; - /* check band count */ - if ( sp->nSamples != 3 + /* check band count */ + if (sp->nSamples != 3 #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - && sp->nSamples != 4 + && sp->nSamples != 4 #endif - ) - { - TIFFErrorExtR(tif, module, - "WEBP driver doesn't support %d bands. Must be 3 (RGB) " + ) + { + TIFFErrorExtR(tif, module, + "WEBP driver doesn't support %d bands. Must be 3 (RGB) " #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - "or 4 (RGBA) " + "or 4 (RGBA) " #endif - "bands.", - sp->nSamples ); - return 0; - } + "bands.", + sp->nSamples); + return 0; + } - /* check bits per sample and data type */ - if ((nBitsPerSample != 8) || (sampleFormat != SAMPLEFORMAT_UINT)) { - TIFFErrorExtR(tif, module, - "WEBP driver requires 8 bit unsigned data"); - return 0; - } + /* check bits per sample and data type */ + if ((nBitsPerSample != 8) || (sampleFormat != SAMPLEFORMAT_UINT)) + { + TIFFErrorExtR(tif, module, "WEBP driver requires 8 bit unsigned data"); + return 0; + } - if (sp->state & LSTATE_INIT_DECODE) { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - sp->last_y = 0; - sp->state = 0; - } + if (sp->state & LSTATE_INIT_DECODE) + { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + sp->last_y = 0; + sp->state = 0; + } - sp->state |= LSTATE_INIT_ENCODE; + sp->state |= LSTATE_INIT_ENCODE; - if (!WebPPictureInit(&sp->sPicture)) { - TIFFErrorExtR(tif, module, - "Error initializing WebP picture."); - return 0; - } + if (!WebPPictureInit(&sp->sPicture)) + { + TIFFErrorExtR(tif, module, "Error initializing WebP picture."); + return 0; + } - if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT, - (float)sp->quality_level, - WEBP_ENCODER_ABI_VERSION)) { - TIFFErrorExtR(tif, module, - "Error creating WebP encoder configuration."); - return 0; - } + if (!WebPConfigInitInternal(&sp->sEncoderConfig, WEBP_PRESET_DEFAULT, + (float)sp->quality_level, + WEBP_ENCODER_ABI_VERSION)) + { + TIFFErrorExtR(tif, module, + "Error creating WebP encoder configuration."); + return 0; + } - // WebPConfigInitInternal above sets lossless to false - #if WEBP_ENCODER_ABI_VERSION >= 0x0100 +// WebPConfigInitInternal above sets lossless to false +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 sp->sEncoderConfig.lossless = sp->lossless; - if (sp->lossless) { - sp->sPicture.use_argb = 1; + if (sp->lossless) + { + sp->sPicture.use_argb = 1; } - #endif +#endif - if (!WebPValidateConfig(&sp->sEncoderConfig)) { - TIFFErrorExtR(tif, module, - "Error with WebP encoder configuration."); - return 0; - } + if (!WebPValidateConfig(&sp->sEncoderConfig)) + { + TIFFErrorExtR(tif, module, "Error with WebP encoder configuration."); + return 0; + } - return 1; + return 1; } /* -* Reset encoding state at the start of a strip. -*/ -static int -TWebPPreEncode(TIFF* tif, uint16_t s) + * Reset encoding state at the start of a strip. + */ +static int TWebPPreEncode(TIFF *tif, uint16_t s) { - static const char module[] = "TWebPPreEncode"; - uint32_t segment_width, segment_height; - WebPState *sp = EncoderState(tif); - TIFFDirectory* td = &tif->tif_dir; - - (void) s; - - assert(sp != NULL); - if( sp->state != LSTATE_INIT_ENCODE ) - tif->tif_setupencode(tif); - - /* - * Set encoding parameters for this strip/tile. - */ - if (isTiled(tif)) { - segment_width = td->td_tilewidth; - segment_height = td->td_tilelength; - } else { - segment_width = td->td_imagewidth; - segment_height = td->td_imagelength - tif->tif_row; - if (segment_height > td->td_rowsperstrip) - segment_height = td->td_rowsperstrip; - } - - if( segment_width > 16383 || segment_height > 16383 ) { - TIFFErrorExtR(tif, module, - "WEBP maximum image dimensions are 16383 x 16383."); - return 0; - } - - /* set up buffer for raw data */ - /* given above check and that nSamples <= 4, buffer_size is <= 1 GB */ - sp->buffer_size = segment_width * segment_height * sp->nSamples; - - if (sp->pBuffer != NULL) { - _TIFFfreeExt(tif, sp->pBuffer); - sp->pBuffer = NULL; - } - - sp->pBuffer = _TIFFmallocExt(tif, sp->buffer_size); - if( !sp->pBuffer) { - TIFFErrorExtR(tif, module, "Cannot allocate buffer"); - return 0; - } - sp->buffer_offset = 0; - - sp->sPicture.width = segment_width; - sp->sPicture.height = segment_height; - sp->sPicture.writer = TWebPDatasetWriter; - sp->sPicture.custom_ptr = tif; - - return 1; + static const char module[] = "TWebPPreEncode"; + uint32_t segment_width, segment_height; + WebPState *sp = EncoderState(tif); + TIFFDirectory *td = &tif->tif_dir; + + (void)s; + + assert(sp != NULL); + if (sp->state != LSTATE_INIT_ENCODE) + tif->tif_setupencode(tif); + + /* + * Set encoding parameters for this strip/tile. + */ + if (isTiled(tif)) + { + segment_width = td->td_tilewidth; + segment_height = td->td_tilelength; + } + else + { + segment_width = td->td_imagewidth; + segment_height = td->td_imagelength - tif->tif_row; + if (segment_height > td->td_rowsperstrip) + segment_height = td->td_rowsperstrip; + } + + if (segment_width > 16383 || segment_height > 16383) + { + TIFFErrorExtR(tif, module, + "WEBP maximum image dimensions are 16383 x 16383."); + return 0; + } + + /* set up buffer for raw data */ + /* given above check and that nSamples <= 4, buffer_size is <= 1 GB */ + sp->buffer_size = segment_width * segment_height * sp->nSamples; + + if (sp->pBuffer != NULL) + { + _TIFFfreeExt(tif, sp->pBuffer); + sp->pBuffer = NULL; + } + + sp->pBuffer = _TIFFmallocExt(tif, sp->buffer_size); + if (!sp->pBuffer) + { + TIFFErrorExtR(tif, module, "Cannot allocate buffer"); + return 0; + } + sp->buffer_offset = 0; + + sp->sPicture.width = segment_width; + sp->sPicture.height = segment_height; + sp->sPicture.writer = TWebPDatasetWriter; + sp->sPicture.custom_ptr = tif; + + return 1; } /* -* Finish off an encoded strip by flushing it. -*/ -static int -TWebPPostEncode(TIFF* tif) + * Finish off an encoded strip by flushing it. + */ +static int TWebPPostEncode(TIFF *tif) { - static const char module[] = "WebPPostEncode"; - int64_t stride; - WebPState *sp = EncoderState(tif); - assert(sp != NULL); + static const char module[] = "WebPPostEncode"; + int64_t stride; + WebPState *sp = EncoderState(tif); + assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); + assert(sp->state == LSTATE_INIT_ENCODE); - stride = (int64_t)sp->sPicture.width * sp->nSamples; + stride = (int64_t)sp->sPicture.width * sp->nSamples; #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - if (sp->nSamples == 4) { - if (!WebPPictureImportRGBA(&sp->sPicture, sp->pBuffer, (int)stride)) { - TIFFErrorExtR(tif, module, - "WebPPictureImportRGBA() failed" ); - return 0; - } - } - else + if (sp->nSamples == 4) + { + if (!WebPPictureImportRGBA(&sp->sPicture, sp->pBuffer, (int)stride)) + { + TIFFErrorExtR(tif, module, "WebPPictureImportRGBA() failed"); + return 0; + } + } + else #endif - if (!WebPPictureImportRGB(&sp->sPicture, sp->pBuffer, (int)stride)) { - TIFFErrorExtR(tif, module, - "WebPPictureImportRGB() failed"); - return 0; - } + if (!WebPPictureImportRGB(&sp->sPicture, sp->pBuffer, (int)stride)) + { + TIFFErrorExtR(tif, module, "WebPPictureImportRGB() failed"); + return 0; + } - if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) { + if (!WebPEncode(&sp->sEncoderConfig, &sp->sPicture)) + { #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - const char* pszErrorMsg = NULL; - switch(sp->sPicture.error_code) { - case VP8_ENC_ERROR_OUT_OF_MEMORY: - pszErrorMsg = "Out of memory"; break; - case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: - pszErrorMsg = "Out of memory while flushing bits"; break; - case VP8_ENC_ERROR_NULL_PARAMETER: - pszErrorMsg = "A pointer parameter is NULL"; break; - case VP8_ENC_ERROR_INVALID_CONFIGURATION: - pszErrorMsg = "Configuration is invalid"; break; - case VP8_ENC_ERROR_BAD_DIMENSION: - pszErrorMsg = "Picture has invalid width/height"; break; - case VP8_ENC_ERROR_PARTITION0_OVERFLOW: - pszErrorMsg = "Partition is bigger than 512k. Try using less " - "SEGMENTS, or increase PARTITION_LIMIT value"; - break; - case VP8_ENC_ERROR_PARTITION_OVERFLOW: - pszErrorMsg = "Partition is bigger than 16M"; - break; - case VP8_ENC_ERROR_BAD_WRITE: - pszErrorMsg = "Error while fludshing bytes"; break; - case VP8_ENC_ERROR_FILE_TOO_BIG: - pszErrorMsg = "File is bigger than 4G"; break; - case VP8_ENC_ERROR_USER_ABORT: - pszErrorMsg = "User interrupted"; - break; - default: - TIFFErrorExtR(tif, module, - "WebPEncode returned an unknown error code: %d", - sp->sPicture.error_code); - pszErrorMsg = "Unknown WebP error type."; - break; - } - TIFFErrorExtR(tif, module, - "WebPEncode() failed : %s", pszErrorMsg); + const char *pszErrorMsg = NULL; + switch (sp->sPicture.error_code) + { + case VP8_ENC_ERROR_OUT_OF_MEMORY: + pszErrorMsg = "Out of memory"; + break; + case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: + pszErrorMsg = "Out of memory while flushing bits"; + break; + case VP8_ENC_ERROR_NULL_PARAMETER: + pszErrorMsg = "A pointer parameter is NULL"; + break; + case VP8_ENC_ERROR_INVALID_CONFIGURATION: + pszErrorMsg = "Configuration is invalid"; + break; + case VP8_ENC_ERROR_BAD_DIMENSION: + pszErrorMsg = "Picture has invalid width/height"; + break; + case VP8_ENC_ERROR_PARTITION0_OVERFLOW: + pszErrorMsg = "Partition is bigger than 512k. Try using less " + "SEGMENTS, or increase PARTITION_LIMIT value"; + break; + case VP8_ENC_ERROR_PARTITION_OVERFLOW: + pszErrorMsg = "Partition is bigger than 16M"; + break; + case VP8_ENC_ERROR_BAD_WRITE: + pszErrorMsg = "Error while fludshing bytes"; + break; + case VP8_ENC_ERROR_FILE_TOO_BIG: + pszErrorMsg = "File is bigger than 4G"; + break; + case VP8_ENC_ERROR_USER_ABORT: + pszErrorMsg = "User interrupted"; + break; + default: + TIFFErrorExtR(tif, module, + "WebPEncode returned an unknown error code: %d", + sp->sPicture.error_code); + pszErrorMsg = "Unknown WebP error type."; + break; + } + TIFFErrorExtR(tif, module, "WebPEncode() failed : %s", pszErrorMsg); #else - TIFFErrorExtR(tif, module, - "Error in WebPEncode()"); + TIFFErrorExtR(tif, module, "Error in WebPEncode()"); #endif - return 0; - } + return 0; + } - sp->sPicture.custom_ptr = NULL; + sp->sPicture.custom_ptr = NULL; - if (!TIFFFlushData1(tif)) - { - TIFFErrorExtR(tif, module, - "Error flushing TIFF WebP encoder."); - return 0; - } + if (!TIFFFlushData1(tif)) + { + TIFFErrorExtR(tif, module, "Error flushing TIFF WebP encoder."); + return 0; + } - return 1; + return 1; } -static void -TWebPCleanup(TIFF* tif) +static void TWebPCleanup(TIFF *tif) { - WebPState* sp = LState(tif); + WebPState *sp = LState(tif); - assert(sp != 0); + assert(sp != 0); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; - if (sp->state & LSTATE_INIT_ENCODE) { - WebPPictureFree(&sp->sPicture); - } + if (sp->state & LSTATE_INIT_ENCODE) + { + WebPPictureFree(&sp->sPicture); + } - if (sp->psDecoder != NULL) { - WebPIDelete(sp->psDecoder); - WebPFreeDecBuffer(&sp->sDecBuffer); - sp->psDecoder = NULL; - sp->last_y = 0; - } + if (sp->psDecoder != NULL) + { + WebPIDelete(sp->psDecoder); + WebPFreeDecBuffer(&sp->sDecBuffer); + sp->psDecoder = NULL; + sp->last_y = 0; + } - if (sp->pBuffer != NULL) { - _TIFFfreeExt(tif, sp->pBuffer); - sp->pBuffer = NULL; - } + if (sp->pBuffer != NULL) + { + _TIFFfreeExt(tif, sp->pBuffer); + sp->pBuffer = NULL; + } - _TIFFfreeExt(tif, tif->tif_data); - tif->tif_data = NULL; + _TIFFfreeExt(tif, tif->tif_data); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } -static int -TWebPVSetField(TIFF* tif, uint32_t tag, va_list ap) +static int TWebPVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[] = "WebPVSetField"; - WebPState* sp = LState(tif); - - switch (tag) { - case TIFFTAG_WEBP_LEVEL: - sp->quality_level = (int) va_arg(ap, int); - if( sp->quality_level <= 0 || - sp->quality_level > 100.0f ) { - TIFFWarningExtR(tif, module, - "WEBP_LEVEL should be between 1 and 100"); - } - return 1; - case TIFFTAG_WEBP_LOSSLESS: - #if WEBP_ENCODER_ABI_VERSION >= 0x0100 - sp->lossless = va_arg(ap, int); - if (sp->lossless){ - sp->quality_level = 100; + static const char module[] = "WebPVSetField"; + WebPState *sp = LState(tif); + + switch (tag) + { + case TIFFTAG_WEBP_LEVEL: + sp->quality_level = (int)va_arg(ap, int); + if (sp->quality_level <= 0 || sp->quality_level > 100.0f) + { + TIFFWarningExtR(tif, module, + "WEBP_LEVEL should be between 1 and 100"); + } + return 1; + case TIFFTAG_WEBP_LOSSLESS: +#if WEBP_ENCODER_ABI_VERSION >= 0x0100 + sp->lossless = va_arg(ap, int); + if (sp->lossless) + { + sp->quality_level = 100; + } + return 1; +#else + TIFFErrorExtR( + tif, module, + "Need to upgrade WEBP driver, this version doesn't support " + "lossless compression."); + return 0; +#endif + default: + return (*sp->vsetparent)(tif, tag, ap); } - return 1; - #else - TIFFErrorExtR(tif, module, - "Need to upgrade WEBP driver, this version doesn't support " - "lossless compression."); - return 0; - #endif - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ + /*NOTREACHED*/ } -static int -TWebPVGetField(TIFF* tif, uint32_t tag, va_list ap) +static int TWebPVGetField(TIFF *tif, uint32_t tag, va_list ap) { - WebPState* sp = LState(tif); - - switch (tag) { - case TIFFTAG_WEBP_LEVEL: - *va_arg(ap, int*) = sp->quality_level; - break; - case TIFFTAG_WEBP_LOSSLESS: - *va_arg(ap, int*) = sp->lossless; - break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; + WebPState *sp = LState(tif); + + switch (tag) + { + case TIFFTAG_WEBP_LEVEL: + *va_arg(ap, int *) = sp->quality_level; + break; + case TIFFTAG_WEBP_LOSSLESS: + *va_arg(ap, int *) = sp->lossless; + break; + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; } static const TIFFField TWebPFields[] = { - { TIFFTAG_WEBP_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, TRUE, FALSE, "WEBP quality", NULL }, - { TIFFTAG_WEBP_LOSSLESS, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, TRUE, FALSE, "WEBP lossless/lossy", NULL - }, + {TIFFTAG_WEBP_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP quality", NULL}, + {TIFFTAG_WEBP_LOSSLESS, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "WEBP lossless/lossy", + NULL}, }; -int -TIFFInitWebP(TIFF* tif, int scheme) +int TIFFInitWebP(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitWebP"; - WebPState* sp; - - (void)scheme; - assert( scheme == COMPRESSION_WEBP ); - - /* - * Merge codec-specific tag information. - */ - if ( !_TIFFMergeFields(tif, TWebPFields, TIFFArrayCount(TWebPFields)) ) { - TIFFErrorExtR(tif, module, - "Merging WebP codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t*) _TIFFmallocExt(tif, sizeof(WebPState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = TWebPVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = TWebPVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->quality_level = 75; /* default comp. level */ - sp->lossless = 0; /* default to false */ - sp->state = 0; - sp->nSamples = 0; - sp->psDecoder = NULL; - sp->last_y = 0; - - sp->buffer_offset = 0; - sp->pBuffer = NULL; - - /* - * Install codec methods. - * Notes: - * encoderow is not supported - */ - tif->tif_fixuptags = TWebPFixupTags; - tif->tif_setupdecode = TWebPSetupDecode; - tif->tif_predecode = TWebPPreDecode; - tif->tif_decoderow = TWebPDecode; - tif->tif_decodestrip = TWebPDecode; - tif->tif_decodetile = TWebPDecode; - tif->tif_setupencode = TWebPSetupEncode; - tif->tif_preencode = TWebPPreEncode; - tif->tif_postencode = TWebPPostEncode; - tif->tif_encoderow = TWebPEncode; - tif->tif_encodestrip = TWebPEncode; - tif->tif_encodetile = TWebPEncode; - tif->tif_cleanup = TWebPCleanup; - - return 1; + static const char module[] = "TIFFInitWebP"; + WebPState *sp; + + (void)scheme; + assert(scheme == COMPRESSION_WEBP); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, TWebPFields, TIFFArrayCount(TWebPFields))) + { + TIFFErrorExtR(tif, module, "Merging WebP codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(WebPState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = TWebPVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = TWebPVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->quality_level = 75; /* default comp. level */ + sp->lossless = 0; /* default to false */ + sp->state = 0; + sp->nSamples = 0; + sp->psDecoder = NULL; + sp->last_y = 0; + + sp->buffer_offset = 0; + sp->pBuffer = NULL; + + /* + * Install codec methods. + * Notes: + * encoderow is not supported + */ + tif->tif_fixuptags = TWebPFixupTags; + tif->tif_setupdecode = TWebPSetupDecode; + tif->tif_predecode = TWebPPreDecode; + tif->tif_decoderow = TWebPDecode; + tif->tif_decodestrip = TWebPDecode; + tif->tif_decodetile = TWebPDecode; + tif->tif_setupencode = TWebPSetupEncode; + tif->tif_preencode = TWebPPreEncode; + tif->tif_postencode = TWebPPostEncode; + tif->tif_encoderow = TWebPEncode; + tif->tif_encodestrip = TWebPEncode; + tif->tif_encodetile = TWebPEncode; + tif->tif_cleanup = TWebPCleanup; + + return 1; bad: - TIFFErrorExtR(tif, module, - "No space for WebP state block"); - return 0; + TIFFErrorExtR(tif, module, "No space for WebP state block"); + return 0; } #endif /* WEBP_SUPPORT */ diff --git a/libtiff/tif_win32.c b/libtiff/tif_win32.c index ced6c4dd..8b476506 100644 --- a/libtiff/tif_win32.c +++ b/libtiff/tif_win32.c @@ -2,23 +2,23 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -55,121 +55,111 @@ static inline thandle_t thandle_from_int(int ifd) return (thandle_t)(intptr_t)ifd; } -static inline int thandle_to_int(thandle_t fd) -{ - return (int)(intptr_t)fd; -} +static inline int thandle_to_int(thandle_t fd) { return (int)(intptr_t)fd; } -static tmsize_t -_tiffReadProc(thandle_t fd, void* buf, tmsize_t size) +static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size) { - /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes - * 32bit sizes, so we loop through the data in suitable 32bit sized - * chunks */ - uint8_t* ma; - uint64_t mb; - DWORD n; - DWORD o; - tmsize_t p; - ma=(uint8_t*)buf; - mb=size; - p=0; - while (mb>0) - { - n=0x80000000UL; - if ((uint64_t)n>mb) - n=(DWORD)mb; - if (!ReadFile(fd,(LPVOID)ma,n,&o,NULL)) - return(0); - ma+=o; - mb-=o; - p+=o; - if (o!=n) - break; - } - return(p); + /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes + * 32bit sizes, so we loop through the data in suitable 32bit sized + * chunks */ + uint8_t *ma; + uint64_t mb; + DWORD n; + DWORD o; + tmsize_t p; + ma = (uint8_t *)buf; + mb = size; + p = 0; + while (mb > 0) + { + n = 0x80000000UL; + if ((uint64_t)n > mb) + n = (DWORD)mb; + if (!ReadFile(fd, (LPVOID)ma, n, &o, NULL)) + return (0); + ma += o; + mb -= o; + p += o; + if (o != n) + break; + } + return (p); } -static tmsize_t -_tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) +static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size) { - /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes - * 32bit sizes, so we loop through the data in suitable 32bit sized - * chunks */ - uint8_t* ma; - uint64_t mb; - DWORD n; - DWORD o; - tmsize_t p; - ma=(uint8_t*)buf; - mb=size; - p=0; - while (mb>0) - { - n=0x80000000UL; - if ((uint64_t)n>mb) - n=(DWORD)mb; - if (!WriteFile(fd,(LPVOID)ma,n,&o,NULL)) - return(0); - ma+=o; - mb-=o; - p+=o; - if (o!=n) - break; - } - return(p); + /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes + * 32bit sizes, so we loop through the data in suitable 32bit sized + * chunks */ + uint8_t *ma; + uint64_t mb; + DWORD n; + DWORD o; + tmsize_t p; + ma = (uint8_t *)buf; + mb = size; + p = 0; + while (mb > 0) + { + n = 0x80000000UL; + if ((uint64_t)n > mb) + n = (DWORD)mb; + if (!WriteFile(fd, (LPVOID)ma, n, &o, NULL)) + return (0); + ma += o; + mb -= o; + p += o; + if (o != n) + break; + } + return (p); } -static uint64_t -_tiffSeekProc(thandle_t fd, uint64_t off, int whence) +static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence) { - LARGE_INTEGER offli; - DWORD dwMoveMethod; - offli.QuadPart = off; - switch(whence) - { - case SEEK_SET: - dwMoveMethod = FILE_BEGIN; - break; - case SEEK_CUR: - dwMoveMethod = FILE_CURRENT; - break; - case SEEK_END: - dwMoveMethod = FILE_END; - break; - default: - dwMoveMethod = FILE_BEGIN; - break; - } - offli.LowPart=SetFilePointer(fd,offli.LowPart,&offli.HighPart,dwMoveMethod); - if ((offli.LowPart==INVALID_SET_FILE_POINTER)&&(GetLastError()!=NO_ERROR)) - offli.QuadPart=0; - return(offli.QuadPart); + LARGE_INTEGER offli; + DWORD dwMoveMethod; + offli.QuadPart = off; + switch (whence) + { + case SEEK_SET: + dwMoveMethod = FILE_BEGIN; + break; + case SEEK_CUR: + dwMoveMethod = FILE_CURRENT; + break; + case SEEK_END: + dwMoveMethod = FILE_END; + break; + default: + dwMoveMethod = FILE_BEGIN; + break; + } + offli.LowPart = + SetFilePointer(fd, offli.LowPart, &offli.HighPart, dwMoveMethod); + if ((offli.LowPart == INVALID_SET_FILE_POINTER) && + (GetLastError() != NO_ERROR)) + offli.QuadPart = 0; + return (offli.QuadPart); } -static int -_tiffCloseProc(thandle_t fd) -{ - return (CloseHandle(fd) ? 0 : -1); -} +static int _tiffCloseProc(thandle_t fd) { return (CloseHandle(fd) ? 0 : -1); } -static uint64_t -_tiffSizeProc(thandle_t fd) +static uint64_t _tiffSizeProc(thandle_t fd) { - LARGE_INTEGER m; - if (GetFileSizeEx(fd,&m)) - return(m.QuadPart); - else - return(0); + LARGE_INTEGER m; + if (GetFileSizeEx(fd, &m)) + return (m.QuadPart); + else + return (0); } -static int -_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) +static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize) { - (void) fd; - (void) pbase; - (void) psize; - return (0); + (void)fd; + (void)pbase; + (void)psize; + return (0); } /* @@ -183,45 +173,42 @@ _tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) * This removes a nasty OS dependency and cures a problem * with Visual C++ 5.0 */ -static int -_tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) +static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize) { - uint64_t size; - tmsize_t sizem; - HANDLE hMapFile; - - size = _tiffSizeProc(fd); - sizem = (tmsize_t)size; - if (!size || (uint64_t)sizem!=size) - return (0); - - /* By passing in 0 for the maximum file size, it specifies that we - create a file mapping object for the full file size. */ - hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); - if (hMapFile == NULL) - return (0); - *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); - CloseHandle(hMapFile); - if (*pbase == NULL) - return (0); - *psize = size; - return(1); + uint64_t size; + tmsize_t sizem; + HANDLE hMapFile; + + size = _tiffSizeProc(fd); + sizem = (tmsize_t)size; + if (!size || (uint64_t)sizem != size) + return (0); + + /* By passing in 0 for the maximum file size, it specifies that we + create a file mapping object for the full file size. */ + hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); + if (hMapFile == NULL) + return (0); + *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); + CloseHandle(hMapFile); + if (*pbase == NULL) + return (0); + *psize = size; + return (1); } -static void -_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) +static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size) { - (void) fd; - (void) base; - (void) size; + (void)fd; + (void)base; + (void)size; } -static void -_tiffUnmapProc(thandle_t fd, void* base, toff_t size) +static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size) { - (void) fd; - (void) size; - UnmapViewOfFile(base); + (void)fd; + (void)size; + UnmapViewOfFile(base); } /* @@ -229,41 +216,36 @@ _tiffUnmapProc(thandle_t fd, void* base, toff_t size) * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode * string, which forces the file to be opened unmapped. */ -TIFF* -TIFFFdOpen(int ifd, const char* name, const char* mode) +TIFF *TIFFFdOpen(int ifd, const char *name, const char *mode) { return TIFFFdOpenExt(ifd, name, mode, NULL); } -TIFF* -TIFFFdOpenExt(int ifd, const char* name, const char* mode, TIFFOpenOptions* opts) +TIFF *TIFFFdOpenExt(int ifd, const char *name, const char *mode, + TIFFOpenOptions *opts) { - TIFF* tif; - int fSuppressMap; - int m; - - fSuppressMap=0; - for (m=0; mode[m]!=0; m++) - { - if (mode[m]=='u') - { - fSuppressMap=1; - break; - } - } - - tif = TIFFClientOpenExt(name, mode, thandle_from_int(ifd), - _tiffReadProc, - _tiffWriteProc, - _tiffSeekProc, - _tiffCloseProc, - _tiffSizeProc, - fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, - fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc, - opts); - if (tif) - tif->tif_fd = ifd; - return (tif); + TIFF *tif; + int fSuppressMap; + int m; + + fSuppressMap = 0; + for (m = 0; mode[m] != 0; m++) + { + if (mode[m] == 'u') + { + fSuppressMap = 1; + break; + } + } + + tif = TIFFClientOpenExt( + name, mode, thandle_from_int(ifd), _tiffReadProc, _tiffWriteProc, + _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, + fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, + fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc, opts); + if (tif) + tif->tif_fd = ifd; + return (tif); } #ifndef _WIN32_WCE @@ -271,182 +253,189 @@ TIFFFdOpenExt(int ifd, const char* name, const char* mode, TIFFOpenOptions* opts /* * Open a TIFF file for read/writing. */ -TIFF* -TIFFOpen(const char* name, const char* mode) +TIFF *TIFFOpen(const char *name, const char *mode) { return TIFFOpenExt(name, mode, NULL); } -TIFF* -TIFFOpenExt(const char* name, const char* mode, TIFFOpenOptions* opts) +TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts) { - static const char module[] = "TIFFOpen"; - thandle_t fd; - int m; - DWORD dwMode; - TIFF* tif; - - m = _TIFFgetMode(opts, NULL, mode, module); - - switch(m) { - case O_RDONLY: dwMode = OPEN_EXISTING; break; - case O_RDWR: dwMode = OPEN_ALWAYS; break; - case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; - case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; - case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; - default: return ((TIFF*)0); - } - - fd = (thandle_t)CreateFileA(name, - (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE), - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, - (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, - NULL); - if (fd == INVALID_HANDLE_VALUE) { - _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name); - return ((TIFF *)0); - } - - tif = TIFFFdOpenExt(thandle_to_int(fd), name, mode, opts); - if(!tif) - CloseHandle(fd); - return tif; + static const char module[] = "TIFFOpen"; + thandle_t fd; + int m; + DWORD dwMode; + TIFF *tif; + + m = _TIFFgetMode(opts, NULL, mode, module); + + switch (m) + { + case O_RDONLY: + dwMode = OPEN_EXISTING; + break; + case O_RDWR: + dwMode = OPEN_ALWAYS; + break; + case O_RDWR | O_CREAT: + dwMode = OPEN_ALWAYS; + break; + case O_RDWR | O_TRUNC: + dwMode = CREATE_ALWAYS; + break; + case O_RDWR | O_CREAT | O_TRUNC: + dwMode = CREATE_ALWAYS; + break; + default: + return ((TIFF *)0); + } + + fd = (thandle_t)CreateFileA( + name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE), + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, + (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL, + NULL); + if (fd == INVALID_HANDLE_VALUE) + { + _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name); + return ((TIFF *)0); + } + + tif = TIFFFdOpenExt(thandle_to_int(fd), name, mode, opts); + if (!tif) + CloseHandle(fd); + return tif; } /* * Open a TIFF file with a Unicode filename, for read/writing. */ -TIFF* -TIFFOpenW(const wchar_t* name, const char* mode) +TIFF *TIFFOpenW(const wchar_t *name, const char *mode) { return TIFFOpenWExt(name, mode, NULL); } -TIFF* -TIFFOpenWExt(const wchar_t* name, const char* mode, TIFFOpenOptions* opts) +TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts) { - static const char module[] = "TIFFOpenW"; - thandle_t fd; - int m; - DWORD dwMode; - int mbsize; - char *mbname; - TIFF *tif; - - m = _TIFFgetMode(opts, NULL, mode, module); - - switch(m) { - case O_RDONLY: dwMode = OPEN_EXISTING; break; - case O_RDWR: dwMode = OPEN_ALWAYS; break; - case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; - case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; - case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; - default: return ((TIFF*)0); - } - - fd = (thandle_t)CreateFileW(name, - (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE), - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, - (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, - NULL); - if (fd == INVALID_HANDLE_VALUE) { - _TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name); - return ((TIFF *)0); - } - - mbname = NULL; - mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); - if (mbsize > 0) { - mbname = (char *)_TIFFmalloc(mbsize); - if (!mbname) { - _TIFFErrorEarly(opts, NULL, module, - "Can't allocate space for filename conversion buffer"); - return ((TIFF*)0); - } - - WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, - NULL, NULL); - } - - tif = TIFFFdOpenExt(thandle_to_int(fd), - (mbname != NULL) ? mbname : "<unknown>", mode, opts); - if(!tif) - CloseHandle(fd); - - _TIFFfree(mbname); - - return tif; + static const char module[] = "TIFFOpenW"; + thandle_t fd; + int m; + DWORD dwMode; + int mbsize; + char *mbname; + TIFF *tif; + + m = _TIFFgetMode(opts, NULL, mode, module); + + switch (m) + { + case O_RDONLY: + dwMode = OPEN_EXISTING; + break; + case O_RDWR: + dwMode = OPEN_ALWAYS; + break; + case O_RDWR | O_CREAT: + dwMode = OPEN_ALWAYS; + break; + case O_RDWR | O_TRUNC: + dwMode = CREATE_ALWAYS; + break; + case O_RDWR | O_CREAT | O_TRUNC: + dwMode = CREATE_ALWAYS; + break; + default: + return ((TIFF *)0); + } + + fd = (thandle_t)CreateFileW( + name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE), + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, + (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL, + NULL); + if (fd == INVALID_HANDLE_VALUE) + { + _TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name); + return ((TIFF *)0); + } + + mbname = NULL; + mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); + if (mbsize > 0) + { + mbname = (char *)_TIFFmalloc(mbsize); + if (!mbname) + { + _TIFFErrorEarly( + opts, NULL, module, + "Can't allocate space for filename conversion buffer"); + return ((TIFF *)0); + } + + WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL); + } + + tif = TIFFFdOpenExt(thandle_to_int(fd), + (mbname != NULL) ? mbname : "<unknown>", mode, opts); + if (!tif) + CloseHandle(fd); + + _TIFFfree(mbname); + + return tif; } #endif /* ndef _WIN32_WCE */ -void* -_TIFFmalloc(tmsize_t s) +void *_TIFFmalloc(tmsize_t s) { - if (s == 0) - return ((void *) NULL); + if (s == 0) + return ((void *)NULL); - return (malloc((size_t) s)); + return (malloc((size_t)s)); } -void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) +void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz) { - if( nmemb == 0 || siz == 0 ) - return ((void *) NULL); + if (nmemb == 0 || siz == 0) + return ((void *)NULL); - return calloc((size_t) nmemb, (size_t)siz); + return calloc((size_t)nmemb, (size_t)siz); } -void -_TIFFfree(void* p) -{ - free(p); -} +void _TIFFfree(void *p) { free(p); } -void* -_TIFFrealloc(void* p, tmsize_t s) -{ - return (realloc(p, (size_t) s)); -} +void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); } -void -_TIFFmemset(void* p, int v, tmsize_t c) -{ - memset(p, v, (size_t) c); -} +void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); } -void -_TIFFmemcpy(void* d, const void* s, tmsize_t c) +void _TIFFmemcpy(void *d, const void *s, tmsize_t c) { - memcpy(d, s, (size_t) c); + memcpy(d, s, (size_t)c); } -int -_TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) +int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c) { - return (memcmp(p1, p2, (size_t) c)); + return (memcmp(p1, p2, (size_t)c)); } #ifndef _WIN32_WCE -static void -Win32WarningHandler(const char* module, const char* fmt, va_list ap) +static void Win32WarningHandler(const char *module, const char *fmt, va_list ap) { - if (module != NULL) - fprintf(stderr, "%s: ", module); - fprintf(stderr, "Warning, "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); + if (module != NULL) + fprintf(stderr, "%s: ", module); + fprintf(stderr, "Warning, "); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); } TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler; -static void -Win32ErrorHandler(const char* module, const char* fmt, va_list ap) +static void Win32ErrorHandler(const char *module, const char *fmt, va_list ap) { - if (module != NULL) - fprintf(stderr, "%s: ", module); - vfprintf(stderr, fmt, ap); - fprintf(stderr, ".\n"); + if (module != NULL) + fprintf(stderr, "%s: ", module); + vfprintf(stderr, fmt, ap); + fprintf(stderr, ".\n"); } TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler; diff --git a/libtiff/tif_write.c b/libtiff/tif_write.c index 496c30d1..6631a782 100644 --- a/libtiff/tif_write.c +++ b/libtiff/tif_write.c @@ -30,162 +30,176 @@ #include "tiffiop.h" #include <stdio.h> -#define STRIPINCR 20 /* expansion factor on strip array */ +#define STRIPINCR 20 /* expansion factor on strip array */ -#define WRITECHECKSTRIPS(tif, module) \ - (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module)) -#define WRITECHECKTILES(tif, module) \ - (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module)) -#define BUFFERCHECK(tif) \ - ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \ - TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1)) +#define WRITECHECKSTRIPS(tif, module) \ + (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module)) +#define WRITECHECKTILES(tif, module) \ + (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 1, module)) +#define BUFFERCHECK(tif) \ + ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \ + TIFFWriteBufferSetup((tif), NULL, (tmsize_t)-1)) -static int TIFFGrowStrips(TIFF* tif, uint32_t delta, const char* module); -static int TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc); +static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module); +static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, + tmsize_t cc); -int -TIFFWriteScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample) +int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample) { - static const char module[] = "TIFFWriteScanline"; - register TIFFDirectory *td; - int status, imagegrew = 0; - uint32_t strip; - - if (!WRITECHECKSTRIPS(tif, module)) - return (-1); - /* - * Handle delayed allocation of data buffer. This - * permits it to be sized more intelligently (using - * directory information). - */ - if (!BUFFERCHECK(tif)) - return (-1); - tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/ - - td = &tif->tif_dir; - /* - * Extend image length if needed - * (but only for PlanarConfig=1). - */ - if (row >= td->td_imagelength) { /* extend image */ - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - TIFFErrorExtR(tif, module, - "Can not change \"ImageLength\" when using separate planes"); - return (-1); - } - td->td_imagelength = row+1; - imagegrew = 1; - } - /* - * Calculate strip and check for crossings. - */ - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - if (sample >= td->td_samplesperpixel) { - TIFFErrorExtR(tif, module, - "%lu: Sample out of range, max %lu", - (unsigned long) sample, (unsigned long) td->td_samplesperpixel); - return (-1); - } - strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; - } else - strip = row / td->td_rowsperstrip; - /* - * Check strip array to make sure there's space. We don't support - * dynamically growing files that have data organized in separate - * bitplanes because it's too painful. In that case we require that - * the imagelength be set properly before the first write (so that the - * strips array will be fully allocated above). - */ - if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module)) - return (-1); - if (strip != tif->tif_curstrip) { - /* - * Changing strips -- flush any data present. - */ - if (!TIFFFlushData(tif)) - return (-1); - tif->tif_curstrip = strip; - /* - * Watch out for a growing image. The value of strips/image - * will initially be 1 (since it can't be deduced until the - * imagelength is known). - */ - if (strip >= td->td_stripsperimage && imagegrew) - td->td_stripsperimage = - TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); - if (td->td_stripsperimage == 0) { - TIFFErrorExtR(tif, module, "Zero strips per image"); - return (-1); - } - tif->tif_row = - (strip % td->td_stripsperimage) * td->td_rowsperstrip; - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { - if (!(*tif->tif_setupencode)(tif)) - return (-1); - tif->tif_flags |= TIFF_CODERSETUP; - } - - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - - /* this informs TIFFAppendToStrip() we have changed strip */ - tif->tif_curoff = 0; - - if (!(*tif->tif_preencode)(tif, sample)) - return (-1); - tif->tif_flags |= TIFF_POSTENCODE; - } - /* - * Ensure the write is either sequential or at the - * beginning of a strip (or that we can randomly - * access the data -- i.e. no encoding). - */ - if (row != tif->tif_row) { - if (row < tif->tif_row) { - /* - * Moving backwards within the same strip: - * backup to the start and then decode - * forward (below). - */ - tif->tif_row = (strip % td->td_stripsperimage) * - td->td_rowsperstrip; - tif->tif_rawcp = tif->tif_rawdata; - } - /* - * Seek forward to the desired row. - */ - if (!(*tif->tif_seek)(tif, row - tif->tif_row)) - return (-1); - tif->tif_row = row; - } - - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t*) buf, tif->tif_scanlinesize ); - - status = (*tif->tif_encoderow)(tif, (uint8_t*) buf, - tif->tif_scanlinesize, sample); - - /* we are now poised at the beginning of the next row */ - tif->tif_row = row + 1; - return (status); + static const char module[] = "TIFFWriteScanline"; + register TIFFDirectory *td; + int status, imagegrew = 0; + uint32_t strip; + + if (!WRITECHECKSTRIPS(tif, module)) + return (-1); + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized more intelligently (using + * directory information). + */ + if (!BUFFERCHECK(tif)) + return (-1); + tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/ + + td = &tif->tif_dir; + /* + * Extend image length if needed + * (but only for PlanarConfig=1). + */ + if (row >= td->td_imagelength) + { /* extend image */ + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + TIFFErrorExtR( + tif, module, + "Can not change \"ImageLength\" when using separate planes"); + return (-1); + } + td->td_imagelength = row + 1; + imagegrew = 1; + } + /* + * Calculate strip and check for crossings. + */ + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + if (sample >= td->td_samplesperpixel) + { + TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu", + (unsigned long)sample, + (unsigned long)td->td_samplesperpixel); + return (-1); + } + strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip; + } + else + strip = row / td->td_rowsperstrip; + /* + * Check strip array to make sure there's space. We don't support + * dynamically growing files that have data organized in separate + * bitplanes because it's too painful. In that case we require that + * the imagelength be set properly before the first write (so that the + * strips array will be fully allocated above). + */ + if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module)) + return (-1); + if (strip != tif->tif_curstrip) + { + /* + * Changing strips -- flush any data present. + */ + if (!TIFFFlushData(tif)) + return (-1); + tif->tif_curstrip = strip; + /* + * Watch out for a growing image. The value of strips/image + * will initially be 1 (since it can't be deduced until the + * imagelength is known). + */ + if (strip >= td->td_stripsperimage && imagegrew) + td->td_stripsperimage = + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); + if (td->td_stripsperimage == 0) + { + TIFFErrorExtR(tif, module, "Zero strips per image"); + return (-1); + } + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) + { + if (!(*tif->tif_setupencode)(tif)) + return (-1); + tif->tif_flags |= TIFF_CODERSETUP; + } + + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + + /* this informs TIFFAppendToStrip() we have changed strip */ + tif->tif_curoff = 0; + + if (!(*tif->tif_preencode)(tif, sample)) + return (-1); + tif->tif_flags |= TIFF_POSTENCODE; + } + /* + * Ensure the write is either sequential or at the + * beginning of a strip (or that we can randomly + * access the data -- i.e. no encoding). + */ + if (row != tif->tif_row) + { + if (row < tif->tif_row) + { + /* + * Moving backwards within the same strip: + * backup to the start and then decode + * forward (below). + */ + tif->tif_row = + (strip % td->td_stripsperimage) * td->td_rowsperstrip; + tif->tif_rawcp = tif->tif_rawdata; + } + /* + * Seek forward to the desired row. + */ + if (!(*tif->tif_seek)(tif, row - tif->tif_row)) + return (-1); + tif->tif_row = row; + } + + /* swab if needed - note that source buffer will be altered */ + tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_scanlinesize); + + status = (*tif->tif_encoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize, + sample); + + /* we are now poised at the beginning of the next row */ + tif->tif_row = row + 1; + return (status); } -/* Make sure that at the first attempt of rewriting a tile/strip, we will have */ +/* Make sure that at the first attempt of rewriting a tile/strip, we will have + */ /* more bytes available in the output buffer than the previous byte count, */ -/* so that TIFFAppendToStrip() will detect the overflow when it is called the first */ +/* so that TIFFAppendToStrip() will detect the overflow when it is called the + * first */ /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */ -static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32_t strip_or_tile) +static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile) { TIFFDirectory *td = &tif->tif_dir; - if( td->td_stripbytecount_p[strip_or_tile] > 0 ) + if (td->td_stripbytecount_p[strip_or_tile] > 0) { /* The +1 is to ensure at least one extra bytes */ /* The +4 is because the LZW encoder flushes 4 bytes before the limit */ - uint64_t safe_buffer_size = (uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4); - if( tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size ) + uint64_t safe_buffer_size = + (uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4); + if (tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size) { - if( !(TIFFWriteBufferSetup(tif, NULL, - (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))) ) + if (!(TIFFWriteBufferSetup( + tif, NULL, + (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024)))) return 0; } } @@ -198,107 +212,112 @@ static int _TIFFReserveLargeEnoughWriteBuffer(TIFF* tif, uint32_t strip_or_tile) * * NB: Image length must be setup before writing. */ -tmsize_t -TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc) +tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data, + tmsize_t cc) { - static const char module[] = "TIFFWriteEncodedStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint16_t sample; - - if (!WRITECHECKSTRIPS(tif, module)) - return ((tmsize_t) -1); - /* - * Check strip array to make sure there's space. - * We don't support dynamically growing files that - * have data organized in separate bitplanes because - * it's too painful. In that case we require that - * the imagelength be set properly before the first - * write (so that the strips array will be fully - * allocated above). - */ - if (strip >= td->td_nstrips) { - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - TIFFErrorExtR(tif, module, - "Can not grow image by strips when using separate planes"); - return ((tmsize_t) -1); - } - if (!TIFFGrowStrips(tif, 1, module)) - return ((tmsize_t) -1); - td->td_stripsperimage = - TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); - } - /* - * Handle delayed allocation of data buffer. This - * permits it to be sized according to the directory - * info. - */ - if (!BUFFERCHECK(tif)) - return ((tmsize_t) -1); - - tif->tif_flags |= TIFF_BUF4WRITE; - - tif->tif_curstrip = strip; - - /* this informs TIFFAppendToStrip() we have changed or reset strip */ - tif->tif_curoff = 0; - - if( !_TIFFReserveLargeEnoughWriteBuffer(tif, strip) ) { - return ((tmsize_t)(-1)); + static const char module[] = "TIFFWriteEncodedStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint16_t sample; + + if (!WRITECHECKSTRIPS(tif, module)) + return ((tmsize_t)-1); + /* + * Check strip array to make sure there's space. + * We don't support dynamically growing files that + * have data organized in separate bitplanes because + * it's too painful. In that case we require that + * the imagelength be set properly before the first + * write (so that the strips array will be fully + * allocated above). + */ + if (strip >= td->td_nstrips) + { + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + TIFFErrorExtR( + tif, module, + "Can not grow image by strips when using separate planes"); + return ((tmsize_t)-1); } + if (!TIFFGrowStrips(tif, 1, module)) + return ((tmsize_t)-1); + td->td_stripsperimage = + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); + } + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized according to the directory + * info. + */ + if (!BUFFERCHECK(tif)) + return ((tmsize_t)-1); - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; + tif->tif_flags |= TIFF_BUF4WRITE; - if (td->td_stripsperimage == 0) { - TIFFErrorExtR(tif, module, "Zero strips per image"); - return ((tmsize_t) -1); - } + tif->tif_curstrip = strip; + + /* this informs TIFFAppendToStrip() we have changed or reset strip */ + tif->tif_curoff = 0; + + if (!_TIFFReserveLargeEnoughWriteBuffer(tif, strip)) + { + return ((tmsize_t)(-1)); + } + + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + + if (td->td_stripsperimage == 0) + { + TIFFErrorExtR(tif, module, "Zero strips per image"); + return ((tmsize_t)-1); + } - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { - if (!(*tif->tif_setupencode)(tif)) - return ((tmsize_t) -1); - tif->tif_flags |= TIFF_CODERSETUP; - } + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) + { + if (!(*tif->tif_setupencode)(tif)) + return ((tmsize_t)-1); + tif->tif_flags |= TIFF_CODERSETUP; + } - tif->tif_flags &= ~TIFF_POSTENCODE; + tif->tif_flags &= ~TIFF_POSTENCODE; /* shortcut to avoid an extra memcpy() */ - if( td->td_compression == COMPRESSION_NONE ) + if (td->td_compression == COMPRESSION_NONE) { /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t*) data, cc ); + tif->tif_postdecode(tif, (uint8_t *)data, cc); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8_t*) data, cc); + TIFFReverseBits((uint8_t *)data, cc); - if (cc > 0 && - !TIFFAppendToStrip(tif, strip, (uint8_t*) data, cc)) - return ((tmsize_t) -1); + if (cc > 0 && !TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc)) + return ((tmsize_t)-1); return (cc); } - sample = (uint16_t)(strip / td->td_stripsperimage); - if (!(*tif->tif_preencode)(tif, sample)) - return ((tmsize_t) -1); + sample = (uint16_t)(strip / td->td_stripsperimage); + if (!(*tif->tif_preencode)(tif, sample)) + return ((tmsize_t)-1); - /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t*) data, cc ); - - if (!(*tif->tif_encodestrip)(tif, (uint8_t*) data, cc, sample)) - return ((tmsize_t) -1); - if (!(*tif->tif_postencode)(tif)) - return ((tmsize_t) -1); - if (!isFillOrder(tif, td->td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc); - if (tif->tif_rawcc > 0 && - !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc)) - return ((tmsize_t) -1); - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - return (cc); + /* swab if needed - note that source buffer will be altered */ + tif->tif_postdecode(tif, (uint8_t *)data, cc); + + if (!(*tif->tif_encodestrip)(tif, (uint8_t *)data, cc, sample)) + return ((tmsize_t)-1); + if (!(*tif->tif_postencode)(tif)) + return ((tmsize_t)-1); + if (!isFillOrder(tif, td->td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc); + if (tif->tif_rawcc > 0 && + !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc)) + return ((tmsize_t)-1); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + return (cc); } /* @@ -306,40 +325,42 @@ TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc) * * NB: Image length must be setup before writing. */ -tmsize_t -TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc) +tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc) { - static const char module[] = "TIFFWriteRawStrip"; - TIFFDirectory *td = &tif->tif_dir; - - if (!WRITECHECKSTRIPS(tif, module)) - return ((tmsize_t) -1); - /* - * Check strip array to make sure there's space. - * We don't support dynamically growing files that - * have data organized in separate bitplanes because - * it's too painful. In that case we require that - * the imagelength be set properly before the first - * write (so that the strips array will be fully - * allocated above). - */ - if (strip >= td->td_nstrips) { - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { - TIFFErrorExtR(tif, module, - "Can not grow image by strips when using separate planes"); - return ((tmsize_t) -1); - } - /* - * Watch out for a growing image. The value of - * strips/image will initially be 1 (since it - * can't be deduced until the imagelength is known). - */ - if (strip >= td->td_stripsperimage) - td->td_stripsperimage = - TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip); - if (!TIFFGrowStrips(tif, 1, module)) - return ((tmsize_t) -1); - } + static const char module[] = "TIFFWriteRawStrip"; + TIFFDirectory *td = &tif->tif_dir; + + if (!WRITECHECKSTRIPS(tif, module)) + return ((tmsize_t)-1); + /* + * Check strip array to make sure there's space. + * We don't support dynamically growing files that + * have data organized in separate bitplanes because + * it's too painful. In that case we require that + * the imagelength be set properly before the first + * write (so that the strips array will be fully + * allocated above). + */ + if (strip >= td->td_nstrips) + { + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + { + TIFFErrorExtR( + tif, module, + "Can not grow image by strips when using separate planes"); + return ((tmsize_t)-1); + } + /* + * Watch out for a growing image. The value of + * strips/image will initially be 1 (since it + * can't be deduced until the imagelength is known). + */ + if (strip >= td->td_stripsperimage) + td->td_stripsperimage = + TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip); + if (!TIFFGrowStrips(tif, 1, module)) + return ((tmsize_t)-1); + } if (tif->tif_curstrip != strip) { @@ -349,32 +370,33 @@ TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc) tif->tif_curoff = 0; } - if (td->td_stripsperimage == 0) { - TIFFErrorExtR(tif, module,"Zero strips per image"); - return ((tmsize_t) -1); - } - tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; - return (TIFFAppendToStrip(tif, strip, (uint8_t*) data, cc) ? - cc : (tmsize_t) -1); + if (td->td_stripsperimage == 0) + { + TIFFErrorExtR(tif, module, "Zero strips per image"); + return ((tmsize_t)-1); + } + tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; + return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc + : (tmsize_t)-1); } /* * Write and compress a tile of data. The * tile is selected by the (x,y,z,s) coordinates. */ -tmsize_t -TIFFWriteTile(TIFF* tif, void* buf, uint32_t x, uint32_t y, uint32_t z, uint16_t s) +tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z, + uint16_t s) { - if (!TIFFCheckTile(tif, x, y, z, s)) - return ((tmsize_t)(-1)); - /* - * NB: A tile size of -1 is used instead of tif_tilesize knowing - * that TIFFWriteEncodedTile will clamp this to the tile size. - * This is done because the tile size may not be defined until - * after the output buffer is setup in TIFFWriteBufferSetup. - */ - return (TIFFWriteEncodedTile(tif, - TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); + if (!TIFFCheckTile(tif, x, y, z, s)) + return ((tmsize_t)(-1)); + /* + * NB: A tile size of -1 is used instead of tif_tilesize knowing + * that TIFFWriteEncodedTile will clamp this to the tile size. + * This is done because the tile size may not be defined until + * after the output buffer is setup in TIFFWriteBufferSetup. + */ + return (TIFFWriteEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf, + (tmsize_t)(-1))); } /* @@ -389,89 +411,92 @@ TIFFWriteTile(TIFF* tif, void* buf, uint32_t x, uint32_t y, uint32_t z, uint16_t * interface does not support automatically growing * the image on each write (as TIFFWriteScanline does). */ -tmsize_t -TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc) +tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc) { - static const char module[] = "TIFFWriteEncodedTile"; - TIFFDirectory *td; - uint16_t sample; - uint32_t howmany32; - - if (!WRITECHECKTILES(tif, module)) - return ((tmsize_t)(-1)); - td = &tif->tif_dir; - if (tile >= td->td_nstrips) { - TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu", - (unsigned long) tile, (unsigned long) td->td_nstrips); - return ((tmsize_t)(-1)); - } - /* - * Handle delayed allocation of data buffer. This - * permits it to be sized more intelligently (using - * directory information). - */ - if (!BUFFERCHECK(tif)) - return ((tmsize_t)(-1)); - - tif->tif_flags |= TIFF_BUF4WRITE; - - tif->tif_curtile = tile; - - /* this informs TIFFAppendToStrip() we have changed or reset tile */ - tif->tif_curoff = 0; - - if( !_TIFFReserveLargeEnoughWriteBuffer(tif, tile) ) { + static const char module[] = "TIFFWriteEncodedTile"; + TIFFDirectory *td; + uint16_t sample; + uint32_t howmany32; + + if (!WRITECHECKTILES(tif, module)) + return ((tmsize_t)(-1)); + td = &tif->tif_dir; + if (tile >= td->td_nstrips) + { + TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu", + (unsigned long)tile, (unsigned long)td->td_nstrips); + return ((tmsize_t)(-1)); + } + /* + * Handle delayed allocation of data buffer. This + * permits it to be sized more intelligently (using + * directory information). + */ + if (!BUFFERCHECK(tif)) + return ((tmsize_t)(-1)); + + tif->tif_flags |= TIFF_BUF4WRITE; + + tif->tif_curtile = tile; + + /* this informs TIFFAppendToStrip() we have changed or reset tile */ + tif->tif_curoff = 0; + + if (!_TIFFReserveLargeEnoughWriteBuffer(tif, tile)) + { + return ((tmsize_t)(-1)); + } + + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + + /* + * Compute tiles per row & per column to compute + * current row and column + */ + howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength); + if (howmany32 == 0) + { + TIFFErrorExtR(tif, module, "Zero tiles"); + return ((tmsize_t)(-1)); + } + tif->tif_row = (tile % howmany32) * td->td_tilelength; + howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); + if (howmany32 == 0) + { + TIFFErrorExtR(tif, module, "Zero tiles"); + return ((tmsize_t)(-1)); + } + tif->tif_col = (tile % howmany32) * td->td_tilewidth; + + if ((tif->tif_flags & TIFF_CODERSETUP) == 0) + { + if (!(*tif->tif_setupencode)(tif)) return ((tmsize_t)(-1)); - } + tif->tif_flags |= TIFF_CODERSETUP; + } + tif->tif_flags &= ~TIFF_POSTENCODE; - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - - /* - * Compute tiles per row & per column to compute - * current row and column - */ - howmany32=TIFFhowmany_32(td->td_imagelength, td->td_tilelength); - if (howmany32 == 0) { - TIFFErrorExtR(tif,module,"Zero tiles"); - return ((tmsize_t)(-1)); - } - tif->tif_row = (tile % howmany32) * td->td_tilelength; - howmany32=TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth); - if (howmany32 == 0) { - TIFFErrorExtR(tif,module,"Zero tiles"); - return ((tmsize_t)(-1)); - } - tif->tif_col = (tile % howmany32) * td->td_tilewidth; - - if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { - if (!(*tif->tif_setupencode)(tif)) - return ((tmsize_t)(-1)); - tif->tif_flags |= TIFF_CODERSETUP; - } - tif->tif_flags &= ~TIFF_POSTENCODE; - - /* - * Clamp write amount to the tile size. This is mostly - * done so that callers can pass in some large number - * (e.g. -1) and have the tile size used instead. - */ - if ( cc < 1 || cc > tif->tif_tilesize) - cc = tif->tif_tilesize; + /* + * Clamp write amount to the tile size. This is mostly + * done so that callers can pass in some large number + * (e.g. -1) and have the tile size used instead. + */ + if (cc < 1 || cc > tif->tif_tilesize) + cc = tif->tif_tilesize; /* shortcut to avoid an extra memcpy() */ - if( td->td_compression == COMPRESSION_NONE ) + if (td->td_compression == COMPRESSION_NONE) { /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t*) data, cc ); + tif->tif_postdecode(tif, (uint8_t *)data, cc); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8_t*) data, cc); + TIFFReverseBits((uint8_t *)data, cc); - if (cc > 0 && - !TIFFAppendToStrip(tif, tile, (uint8_t*) data, cc)) - return ((tmsize_t) -1); + if (cc > 0 && !TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc)) + return ((tmsize_t)-1); return (cc); } @@ -479,18 +504,18 @@ TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc) if (!(*tif->tif_preencode)(tif, sample)) return ((tmsize_t)(-1)); /* swab if needed - note that source buffer will be altered */ - tif->tif_postdecode(tif, (uint8_t*) data, cc ); + tif->tif_postdecode(tif, (uint8_t *)data, cc); - if (!(*tif->tif_encodetile)(tif, (uint8_t*) data, cc, sample)) - return ((tmsize_t) -1); + if (!(*tif->tif_encodetile)(tif, (uint8_t *)data, cc, sample)) + return ((tmsize_t)-1); if (!(*tif->tif_postencode)(tif)) - return ((tmsize_t)(-1)); + return ((tmsize_t)(-1)); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8_t*)tif->tif_rawdata, tif->tif_rawcc); - if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile, - tif->tif_rawdata, tif->tif_rawcc)) - return ((tmsize_t)(-1)); + TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc); + if (tif->tif_rawcc > 0 && + !TIFFAppendToStrip(tif, tile, tif->tif_rawdata, tif->tif_rawcc)) + return ((tmsize_t)(-1)); tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; return (cc); @@ -505,66 +530,64 @@ TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc) * interface does not support automatically growing * the image on each write (as TIFFWriteScanline does). */ -tmsize_t -TIFFWriteRawTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc) +tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc) { - static const char module[] = "TIFFWriteRawTile"; - - if (!WRITECHECKTILES(tif, module)) - return ((tmsize_t)(-1)); - if (tile >= tif->tif_dir.td_nstrips) { - TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu", - (unsigned long) tile, - (unsigned long) tif->tif_dir.td_nstrips); - return ((tmsize_t)(-1)); - } - return (TIFFAppendToStrip(tif, tile, (uint8_t*) data, cc) ? - cc : (tmsize_t)(-1)); + static const char module[] = "TIFFWriteRawTile"; + + if (!WRITECHECKTILES(tif, module)) + return ((tmsize_t)(-1)); + if (tile >= tif->tif_dir.td_nstrips) + { + TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu", + (unsigned long)tile, + (unsigned long)tif->tif_dir.td_nstrips); + return ((tmsize_t)(-1)); + } + return (TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc) ? cc + : (tmsize_t)(-1)); } -#define isUnspecified(tif, f) \ - (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0) +#define isUnspecified(tif, f) \ + (TIFFFieldSet(tif, f) && (tif)->tif_dir.td_imagelength == 0) -int -TIFFSetupStrips(TIFF* tif) +int TIFFSetupStrips(TIFF *tif) { - TIFFDirectory* td = &tif->tif_dir; - - if (isTiled(tif)) - td->td_stripsperimage = - isUnspecified(tif, FIELD_TILEDIMENSIONS) ? - td->td_samplesperpixel : TIFFNumberOfTiles(tif); - else - td->td_stripsperimage = - isUnspecified(tif, FIELD_ROWSPERSTRIP) ? - td->td_samplesperpixel : TIFFNumberOfStrips(tif); - td->td_nstrips = td->td_stripsperimage; - /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */ - if( td->td_nstrips >= 0x80000000U / ((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U) ) - { - TIFFErrorExtR(tif, "TIFFSetupStrips", - "Too large Strip/Tile Offsets/ByteCounts arrays"); - return 0; - } - if (td->td_planarconfig == PLANARCONFIG_SEPARATE) - td->td_stripsperimage /= td->td_samplesperpixel; - td->td_stripoffset_p = (uint64_t *) - _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64_t), - "for \"StripOffsets\" array"); - td->td_stripbytecount_p = (uint64_t *) - _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64_t), - "for \"StripByteCounts\" array"); - if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL) - return (0); - /* - * Place data at the end-of-file - * (by setting offsets to zero). - */ - _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips*sizeof (uint64_t)); - _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips*sizeof (uint64_t)); - TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); - TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); - return (1); + TIFFDirectory *td = &tif->tif_dir; + + if (isTiled(tif)) + td->td_stripsperimage = isUnspecified(tif, FIELD_TILEDIMENSIONS) + ? td->td_samplesperpixel + : TIFFNumberOfTiles(tif); + else + td->td_stripsperimage = isUnspecified(tif, FIELD_ROWSPERSTRIP) + ? td->td_samplesperpixel + : TIFFNumberOfStrips(tif); + td->td_nstrips = td->td_stripsperimage; + /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */ + if (td->td_nstrips >= + 0x80000000U / ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U)) + { + TIFFErrorExtR(tif, "TIFFSetupStrips", + "Too large Strip/Tile Offsets/ByteCounts arrays"); + return 0; + } + if (td->td_planarconfig == PLANARCONFIG_SEPARATE) + td->td_stripsperimage /= td->td_samplesperpixel; + td->td_stripoffset_p = (uint64_t *)_TIFFCheckMalloc( + tif, td->td_nstrips, sizeof(uint64_t), "for \"StripOffsets\" array"); + td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc( + tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array"); + if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL) + return (0); + /* + * Place data at the end-of-file + * (by setting offsets to zero). + */ + _TIFFmemset(td->td_stripoffset_p, 0, td->td_nstrips * sizeof(uint64_t)); + _TIFFmemset(td->td_stripbytecount_p, 0, td->td_nstrips * sizeof(uint64_t)); + TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS); + TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS); + return (1); } #undef isUnspecified @@ -574,236 +597,247 @@ TIFFSetupStrips(TIFF* tif) * we also "freeze" the state of the directory so * that important information is not changed. */ -int -TIFFWriteCheck(TIFF* tif, int tiles, const char* module) +int TIFFWriteCheck(TIFF *tif, int tiles, const char *module) { - if (tif->tif_mode == O_RDONLY) { - TIFFErrorExtR(tif, module, "File not open for writing"); - return (0); - } - if (tiles ^ isTiled(tif)) { - TIFFErrorExtR(tif, module, tiles ? - "Can not write tiles to a striped image" : - "Can not write scanlines to a tiled image"); - return (0); - } - - _TIFFFillStriles( tif ); - - /* - * On the first write verify all the required information - * has been setup and initialize any data structures that - * had to wait until directory information was set. - * Note that a lot of our work is assumed to remain valid - * because we disallow any of the important parameters - * from changing after we start writing (i.e. once - * TIFF_BEENWRITING is set, TIFFSetField will only allow - * the image's length to be changed). - */ - if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) { - TIFFErrorExtR(tif, module, - "Must set \"ImageWidth\" before writing data"); - return (0); - } - if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) { - tif->tif_dir.td_nstrips = 0; - TIFFErrorExtR(tif, module, "No space for %s arrays", - isTiled(tif) ? "tile" : "strip"); - return (0); - } - if (isTiled(tif)) - { - tif->tif_tilesize = TIFFTileSize(tif); - if (tif->tif_tilesize == 0) - return (0); - } - else - tif->tif_tilesize = (tmsize_t)(-1); - tif->tif_scanlinesize = TIFFScanlineSize(tif); - if (tif->tif_scanlinesize == 0) - return (0); - tif->tif_flags |= TIFF_BEENWRITING; - - if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && - tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && - tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && - tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 && - !(tif->tif_flags & TIFF_DIRTYDIRECT) ) - { - TIFFForceStrileArrayWriting(tif); - } + if (tif->tif_mode == O_RDONLY) + { + TIFFErrorExtR(tif, module, "File not open for writing"); + return (0); + } + if (tiles ^ isTiled(tif)) + { + TIFFErrorExtR(tif, module, + tiles ? "Can not write tiles to a striped image" + : "Can not write scanlines to a tiled image"); + return (0); + } - return (1); + _TIFFFillStriles(tif); + + /* + * On the first write verify all the required information + * has been setup and initialize any data structures that + * had to wait until directory information was set. + * Note that a lot of our work is assumed to remain valid + * because we disallow any of the important parameters + * from changing after we start writing (i.e. once + * TIFF_BEENWRITING is set, TIFFSetField will only allow + * the image's length to be changed). + */ + if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) + { + TIFFErrorExtR(tif, module, + "Must set \"ImageWidth\" before writing data"); + return (0); + } + if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif)) + { + tif->tif_dir.td_nstrips = 0; + TIFFErrorExtR(tif, module, "No space for %s arrays", + isTiled(tif) ? "tile" : "strip"); + return (0); + } + if (isTiled(tif)) + { + tif->tif_tilesize = TIFFTileSize(tif); + if (tif->tif_tilesize == 0) + return (0); + } + else + tif->tif_tilesize = (tmsize_t)(-1); + tif->tif_scanlinesize = TIFFScanlineSize(tif); + if (tif->tif_scanlinesize == 0) + return (0); + tif->tif_flags |= TIFF_BEENWRITING; + + if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 && + tif->tif_dir.td_stripoffset_entry.tdir_count == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_type == 0 && + tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 && + tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 && + !(tif->tif_flags & TIFF_DIRTYDIRECT)) + { + TIFFForceStrileArrayWriting(tif); + } + + return (1); } /* * Setup the raw data buffer used for encoding. */ -int -TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size) +int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size) { - static const char module[] = "TIFFWriteBufferSetup"; - - if (tif->tif_rawdata) { - if (tif->tif_flags & TIFF_MYBUFFER) { - _TIFFfreeExt(tif, tif->tif_rawdata); - tif->tif_flags &= ~TIFF_MYBUFFER; - } - tif->tif_rawdata = NULL; - } - if (size == (tmsize_t)(-1)) { - size = (isTiled(tif) ? - tif->tif_tilesize : TIFFStripSize(tif)); - - /* Adds 10% margin for cases where compression would expand a bit */ - if( size < TIFF_TMSIZE_T_MAX - size / 10 ) - size += size / 10; - /* - * Make raw data buffer at least 8K - */ - if (size < 8*1024) - size = 8*1024; - bp = NULL; /* NB: force malloc */ - } - if (bp == NULL) { - bp = _TIFFmallocExt(tif, size); - if (bp == NULL) { - TIFFErrorExtR(tif, module, "No space for output buffer"); - return (0); - } - tif->tif_flags |= TIFF_MYBUFFER; - } else - tif->tif_flags &= ~TIFF_MYBUFFER; - tif->tif_rawdata = (uint8_t*) bp; - tif->tif_rawdatasize = size; - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - tif->tif_flags |= TIFF_BUFFERSETUP; - return (1); + static const char module[] = "TIFFWriteBufferSetup"; + + if (tif->tif_rawdata) + { + if (tif->tif_flags & TIFF_MYBUFFER) + { + _TIFFfreeExt(tif, tif->tif_rawdata); + tif->tif_flags &= ~TIFF_MYBUFFER; + } + tif->tif_rawdata = NULL; + } + if (size == (tmsize_t)(-1)) + { + size = (isTiled(tif) ? tif->tif_tilesize : TIFFStripSize(tif)); + + /* Adds 10% margin for cases where compression would expand a bit */ + if (size < TIFF_TMSIZE_T_MAX - size / 10) + size += size / 10; + /* + * Make raw data buffer at least 8K + */ + if (size < 8 * 1024) + size = 8 * 1024; + bp = NULL; /* NB: force malloc */ + } + if (bp == NULL) + { + bp = _TIFFmallocExt(tif, size); + if (bp == NULL) + { + TIFFErrorExtR(tif, module, "No space for output buffer"); + return (0); + } + tif->tif_flags |= TIFF_MYBUFFER; + } + else + tif->tif_flags &= ~TIFF_MYBUFFER; + tif->tif_rawdata = (uint8_t *)bp; + tif->tif_rawdatasize = size; + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + tif->tif_flags |= TIFF_BUFFERSETUP; + return (1); } /* * Grow the strip data structures by delta strips. */ -static int -TIFFGrowStrips(TIFF* tif, uint32_t delta, const char* module) +static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module) { - TIFFDirectory *td = &tif->tif_dir; - uint64_t* new_stripoffset; - uint64_t* new_stripbytecount; - - assert(td->td_planarconfig == PLANARCONFIG_CONTIG); - new_stripoffset = (uint64_t*)_TIFFreallocExt(tif, td->td_stripoffset_p, - (td->td_nstrips + delta) * sizeof (uint64_t)); - new_stripbytecount = (uint64_t*)_TIFFreallocExt(tif, td->td_stripbytecount_p, - (td->td_nstrips + delta) * sizeof (uint64_t)); - if (new_stripoffset == NULL || new_stripbytecount == NULL) { - if (new_stripoffset) - _TIFFfreeExt(tif, new_stripoffset); - if (new_stripbytecount) - _TIFFfreeExt(tif, new_stripbytecount); - td->td_nstrips = 0; - TIFFErrorExtR(tif, module, "No space to expand strip arrays"); - return (0); - } - td->td_stripoffset_p = new_stripoffset; - td->td_stripbytecount_p = new_stripbytecount; - _TIFFmemset(td->td_stripoffset_p + td->td_nstrips, - 0, delta*sizeof (uint64_t)); - _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, - 0, delta*sizeof (uint64_t)); - td->td_nstrips += delta; - tif->tif_flags |= TIFF_DIRTYDIRECT; - - return (1); + TIFFDirectory *td = &tif->tif_dir; + uint64_t *new_stripoffset; + uint64_t *new_stripbytecount; + + assert(td->td_planarconfig == PLANARCONFIG_CONTIG); + new_stripoffset = (uint64_t *)_TIFFreallocExt( + tif, td->td_stripoffset_p, (td->td_nstrips + delta) * sizeof(uint64_t)); + new_stripbytecount = (uint64_t *)_TIFFreallocExt( + tif, td->td_stripbytecount_p, + (td->td_nstrips + delta) * sizeof(uint64_t)); + if (new_stripoffset == NULL || new_stripbytecount == NULL) + { + if (new_stripoffset) + _TIFFfreeExt(tif, new_stripoffset); + if (new_stripbytecount) + _TIFFfreeExt(tif, new_stripbytecount); + td->td_nstrips = 0; + TIFFErrorExtR(tif, module, "No space to expand strip arrays"); + return (0); + } + td->td_stripoffset_p = new_stripoffset; + td->td_stripbytecount_p = new_stripbytecount; + _TIFFmemset(td->td_stripoffset_p + td->td_nstrips, 0, + delta * sizeof(uint64_t)); + _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0, + delta * sizeof(uint64_t)); + td->td_nstrips += delta; + tif->tif_flags |= TIFF_DIRTYDIRECT; + + return (1); } /* * Append the data to the specified strip. */ -static int -TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) +static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data, + tmsize_t cc) { - static const char module[] = "TIFFAppendToStrip"; - TIFFDirectory *td = &tif->tif_dir; - uint64_t m; + static const char module[] = "TIFFAppendToStrip"; + TIFFDirectory *td = &tif->tif_dir; + uint64_t m; int64_t old_byte_count = -1; - if( tif->tif_curoff == 0 ) + if (tif->tif_curoff == 0) tif->tif_lastvalidoff = 0; - if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) { - assert(td->td_nstrips > 0); + if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0) + { + assert(td->td_nstrips > 0); - if( td->td_stripbytecount_p[strip] != 0 - && td->td_stripoffset_p[strip] != 0 - && td->td_stripbytecount_p[strip] >= (uint64_t) cc ) - { - /* - * There is already tile data on disk, and the new tile - * data we have will fit in the same space. The only - * aspect of this that is risky is that there could be - * more data to append to this strip before we are done - * depending on how we are getting called. - */ - if (!SeekOK(tif, td->td_stripoffset_p[strip])) { - TIFFErrorExtR(tif, module, - "Seek error at scanline %lu", - (unsigned long)tif->tif_row); - return (0); - } - - tif->tif_lastvalidoff = td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip]; - } - else + if (td->td_stripbytecount_p[strip] != 0 && + td->td_stripoffset_p[strip] != 0 && + td->td_stripbytecount_p[strip] >= (uint64_t)cc) + { + /* + * There is already tile data on disk, and the new tile + * data we have will fit in the same space. The only + * aspect of this that is risky is that there could be + * more data to append to this strip before we are done + * depending on how we are getting called. + */ + if (!SeekOK(tif, td->td_stripoffset_p[strip])) { - /* - * Seek to end of file, and set that as our location to - * write this strip. - */ - td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END); - tif->tif_flags |= TIFF_DIRTYSTRIP; + TIFFErrorExtR(tif, module, "Seek error at scanline %lu", + (unsigned long)tif->tif_row); + return (0); } - tif->tif_curoff = td->td_stripoffset_p[strip]; - + tif->tif_lastvalidoff = + td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip]; + } + else + { /* - * We are starting a fresh strip/tile, so set the size to zero. + * Seek to end of file, and set that as our location to + * write this strip. */ - old_byte_count = td->td_stripbytecount_p[strip]; - td->td_stripbytecount_p[strip] = 0; - } - - m = tif->tif_curoff+cc; - if (!(tif->tif_flags&TIFF_BIGTIFF)) - m = (uint32_t)m; - if ((m<tif->tif_curoff)||(m<(uint64_t)cc)) - { - TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); - return (0); - } - - if( tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff && - td->td_stripbytecount_p[strip] > 0 ) + td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END); + tif->tif_flags |= TIFF_DIRTYSTRIP; + } + + tif->tif_curoff = td->td_stripoffset_p[strip]; + + /* + * We are starting a fresh strip/tile, so set the size to zero. + */ + old_byte_count = td->td_stripbytecount_p[strip]; + td->td_stripbytecount_p[strip] = 0; + } + + m = tif->tif_curoff + cc; + if (!(tif->tif_flags & TIFF_BIGTIFF)) + m = (uint32_t)m; + if ((m < tif->tif_curoff) || (m < (uint64_t)cc)) + { + TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); + return (0); + } + + if (tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff && + td->td_stripbytecount_p[strip] > 0) { /* Ouch: we have detected that we are rewriting in place a strip/tile */ /* with several calls to TIFFAppendToStrip(). The first call was with */ /* a size smaller than the previous size of the strip/tile, so we */ /* opted to rewrite in place, but a following call causes us to go */ /* outsize of the strip/tile area, so we have to finally go for a */ - /* append-at-end-of-file strategy, and start by moving what we already */ + /* append-at-end-of-file strategy, and start by moving what we already + */ /* wrote. */ tmsize_t tempSize; - void* temp; + void *temp; uint64_t offsetRead; uint64_t offsetWrite; uint64_t toCopy = td->td_stripbytecount_p[strip]; - if( toCopy < 1024 * 1024 ) + if (toCopy < 1024 * 1024) tempSize = (tmsize_t)toCopy; else tempSize = 1024 * 1024; @@ -812,14 +846,15 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) offsetWrite = TIFFSeekFile(tif, 0, SEEK_END); m = offsetWrite + toCopy + cc; - if (!(tif->tif_flags&TIFF_BIGTIFF) && m != (uint32_t)m) + if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m) { TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded"); return (0); } temp = _TIFFmallocExt(tif, tempSize); - if (temp == NULL) { + if (temp == NULL) + { TIFFErrorExtR(tif, module, "No space for output buffer"); return (0); } @@ -830,24 +865,28 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) td->td_stripbytecount_p[strip] = 0; /* Move data written by previous calls to us at end of file */ - while( toCopy > 0 ) + while (toCopy > 0) { - if( !SeekOK(tif, offsetRead) ) { + if (!SeekOK(tif, offsetRead)) + { TIFFErrorExtR(tif, module, "Seek error"); _TIFFfreeExt(tif, temp); return (0); } - if( !ReadOK(tif, temp, tempSize) ) { + if (!ReadOK(tif, temp, tempSize)) + { TIFFErrorExtR(tif, module, "Cannot read"); _TIFFfreeExt(tif, temp); return (0); } - if (!SeekOK(tif, offsetWrite) ) { + if (!SeekOK(tif, offsetWrite)) + { TIFFErrorExtR(tif, module, "Seek error"); _TIFFfreeExt(tif, temp); return (0); } - if( !WriteOK(tif, temp, tempSize) ) { + if (!WriteOK(tif, temp, tempSize)) + { TIFFErrorExtR(tif, module, "Cannot write"); _TIFFfreeExt(tif, temp); return (0); @@ -864,18 +903,19 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) m = offsetWrite; } - if (!WriteOK(tif, data, cc)) { - TIFFErrorExtR(tif, module, "Write error at scanline %lu", - (unsigned long) tif->tif_row); - return (0); - } - tif->tif_curoff = m; - td->td_stripbytecount_p[strip] += cc; + if (!WriteOK(tif, data, cc)) + { + TIFFErrorExtR(tif, module, "Write error at scanline %lu", + (unsigned long)tif->tif_row); + return (0); + } + tif->tif_curoff = m; + td->td_stripbytecount_p[strip] += cc; - if((int64_t) td->td_stripbytecount_p[strip] != old_byte_count ) - tif->tif_flags |= TIFF_DIRTYSTRIP; + if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count) + tif->tif_flags |= TIFF_DIRTYSTRIP; - return (1); + return (1); } /* @@ -883,29 +923,28 @@ TIFFAppendToStrip(TIFF* tif, uint32_t strip, uint8_t* data, tmsize_t cc) * called by ``encodestrip routines'' w/o concern * for infinite recursion. */ -int -TIFFFlushData1(TIFF* tif) +int TIFFFlushData1(TIFF *tif) { - if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) { - if (!isFillOrder(tif, tif->tif_dir.td_fillorder) && - (tif->tif_flags & TIFF_NOBITREV) == 0) - TIFFReverseBits((uint8_t*)tif->tif_rawdata, - tif->tif_rawcc); - if (!TIFFAppendToStrip(tif, - isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, - tif->tif_rawdata, tif->tif_rawcc)) + if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE) + { + if (!isFillOrder(tif, tif->tif_dir.td_fillorder) && + (tif->tif_flags & TIFF_NOBITREV) == 0) + TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc); + if (!TIFFAppendToStrip( + tif, isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, + tif->tif_rawdata, tif->tif_rawcc)) { /* We update those variables even in case of error since there's */ /* code that doesn't really check the return code of this */ /* function */ tif->tif_rawcc = 0; tif->tif_rawcp = tif->tif_rawdata; - return (0); + return (0); } - tif->tif_rawcc = 0; - tif->tif_rawcp = tif->tif_rawdata; - } - return (1); + tif->tif_rawcc = 0; + tif->tif_rawcp = tif->tif_rawdata; + } + return (1); } /* @@ -914,9 +953,8 @@ TIFFFlushData1(TIFF* tif) * (very carefully), or to 0 so that the next write gets * appended to the end of the file. */ -void -TIFFSetWriteOffset(TIFF* tif, toff_t off) +void TIFFSetWriteOffset(TIFF *tif, toff_t off) { - tif->tif_curoff = off; - tif->tif_lastvalidoff = 0; + tif->tif_curoff = off; + tif->tif_lastvalidoff = 0; } diff --git a/libtiff/tif_zip.c b/libtiff/tif_zip.c index 674ee836..fcf51004 100644 --- a/libtiff/tif_zip.c +++ b/libtiff/tif_zip.c @@ -2,23 +2,23 @@ * Copyright (c) 1995-1997 Sam Leffler * Copyright (c) 1995-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ @@ -57,637 +57,675 @@ #error "Antiquated ZLIB software; you must use version 1.0 or later" #endif -#define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg) +#define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg) /* * State block for each open TIFF * file using ZIP compression/decompression. */ -typedef struct { - TIFFPredictorState predict; - z_stream stream; - int zipquality; /* compression level */ - int state; /* state flags */ - int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */ +typedef struct +{ + TIFFPredictorState predict; + z_stream stream; + int zipquality; /* compression level */ + int state; /* state flags */ + int subcodec; /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */ #if LIBDEFLATE_SUPPORT - int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is called, 0 = use zlib, 1 = use libdeflate */ - struct libdeflate_decompressor* libdeflate_dec; - struct libdeflate_compressor* libdeflate_enc; + int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is + called, 0 = use zlib, 1 = use libdeflate */ + struct libdeflate_decompressor *libdeflate_dec; + struct libdeflate_compressor *libdeflate_enc; #endif #define ZSTATE_INIT_DECODE 0x01 #define ZSTATE_INIT_ENCODE 0x02 - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ } ZIPState; -#define ZState(tif) ((ZIPState*) (tif)->tif_data) -#define DecoderState(tif) ZState(tif) -#define EncoderState(tif) ZState(tif) +#define ZState(tif) ((ZIPState *)(tif)->tif_data) +#define DecoderState(tif) ZState(tif) +#define EncoderState(tif) ZState(tif) -static int ZIPEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s); -static int ZIPDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s); +static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -static int -ZIPFixupTags(TIFF* tif) +static int ZIPFixupTags(TIFF *tif) { - (void) tif; - return (1); + (void)tif; + return (1); } -static int -ZIPSetupDecode(TIFF* tif) +static int ZIPSetupDecode(TIFF *tif) { - static const char module[] = "ZIPSetupDecode"; - ZIPState* sp = DecoderState(tif); - - assert(sp != NULL); - - /* if we were last encoding, terminate this mode */ - if (sp->state & ZSTATE_INIT_ENCODE) { - deflateEnd(&sp->stream); - sp->state = 0; - } - - /* This function can possibly be called several times by */ - /* PredictorSetupDecode() if this function succeeds but */ - /* PredictorSetup() fails */ - if ((sp->state & ZSTATE_INIT_DECODE) == 0 && - inflateInit(&sp->stream) != Z_OK) { - TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp)); - return (0); - } else { - sp->state |= ZSTATE_INIT_DECODE; - return (1); - } + static const char module[] = "ZIPSetupDecode"; + ZIPState *sp = DecoderState(tif); + + assert(sp != NULL); + + /* if we were last encoding, terminate this mode */ + if (sp->state & ZSTATE_INIT_ENCODE) + { + deflateEnd(&sp->stream); + sp->state = 0; + } + + /* This function can possibly be called several times by */ + /* PredictorSetupDecode() if this function succeeds but */ + /* PredictorSetup() fails */ + if ((sp->state & ZSTATE_INIT_DECODE) == 0 && + inflateInit(&sp->stream) != Z_OK) + { + TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp)); + return (0); + } + else + { + sp->state |= ZSTATE_INIT_DECODE; + return (1); + } } /* * Setup state for decoding a strip. */ -static int -ZIPPreDecode(TIFF* tif, uint16_t s) +static int ZIPPreDecode(TIFF *tif, uint16_t s) { - ZIPState* sp = DecoderState(tif); + ZIPState *sp = DecoderState(tif); - (void) s; - assert(sp != NULL); + (void)s; + assert(sp != NULL); - if( (sp->state & ZSTATE_INIT_DECODE) == 0 ) - tif->tif_setupdecode( tif ); + if ((sp->state & ZSTATE_INIT_DECODE) == 0) + tif->tif_setupdecode(tif); #if LIBDEFLATE_SUPPORT - sp->libdeflate_state = -1; + sp->libdeflate_state = -1; #endif - sp->stream.next_in = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_in = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU ? (uInt) tif->tif_rawcc : 0xFFFFFFFFU; - return (inflateReset(&sp->stream) == Z_OK); + sp->stream.next_in = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_in = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU + ? (uInt)tif->tif_rawcc + : 0xFFFFFFFFU; + return (inflateReset(&sp->stream) == Z_OK); } -static int -ZIPDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) +static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "ZIPDecode"; - ZIPState* sp = DecoderState(tif); + static const char module[] = "ZIPDecode"; + ZIPState *sp = DecoderState(tif); - (void) s; - assert(sp != NULL); - assert(sp->state == ZSTATE_INIT_DECODE); + (void)s; + assert(sp != NULL); + assert(sp->state == ZSTATE_INIT_DECODE); #if LIBDEFLATE_SUPPORT - if( sp->libdeflate_state == 1 ) - return 0; - - /* If we have libdeflate support and we are asked to read a whole */ - /* strip/tile, then go for using it */ - do { - TIFFDirectory *td = &tif->tif_dir; - - if( sp->libdeflate_state == 0 ) - break; - if( sp->subcodec == DEFLATE_SUBCODEC_ZLIB ) - break; - - /* Check if we are in the situation where we can use libdeflate */ - if (isTiled(tif)) { - if( TIFFTileSize64(tif) != (uint64_t)occ ) - break; - } else { - uint32_t strip_height = td->td_imagelength - tif->tif_row; - if (strip_height > td->td_rowsperstrip) - strip_height = td->td_rowsperstrip; - if( TIFFVStripSize64(tif, strip_height) != (uint64_t)occ ) - break; - } - - /* Check for overflow */ - if( (size_t)tif->tif_rawcc != (uint64_t)tif->tif_rawcc ) + if (sp->libdeflate_state == 1) + return 0; + + /* If we have libdeflate support and we are asked to read a whole */ + /* strip/tile, then go for using it */ + do + { + TIFFDirectory *td = &tif->tif_dir; + + if (sp->libdeflate_state == 0) + break; + if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB) + break; + + /* Check if we are in the situation where we can use libdeflate */ + if (isTiled(tif)) + { + if (TIFFTileSize64(tif) != (uint64_t)occ) break; - if( (size_t)occ != (uint64_t)occ ) + } + else + { + uint32_t strip_height = td->td_imagelength - tif->tif_row; + if (strip_height > td->td_rowsperstrip) + strip_height = td->td_rowsperstrip; + if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ) break; - - /* Go for decompression using libdeflate */ + } + + /* Check for overflow */ + if ((size_t)tif->tif_rawcc != (uint64_t)tif->tif_rawcc) + break; + if ((size_t)occ != (uint64_t)occ) + break; + + /* Go for decompression using libdeflate */ + { + enum libdeflate_result res; + if (sp->libdeflate_dec == NULL) { - enum libdeflate_result res; - if( sp->libdeflate_dec == NULL ) + sp->libdeflate_dec = libdeflate_alloc_decompressor(); + if (sp->libdeflate_dec == NULL) { - sp->libdeflate_dec = libdeflate_alloc_decompressor(); - if( sp->libdeflate_dec == NULL ) - { - break; - } + break; } + } - sp->libdeflate_state = 1; - - res = libdeflate_zlib_decompress( - sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc, op, (size_t)occ, NULL); + sp->libdeflate_state = 1; - tif->tif_rawcp += tif->tif_rawcc; - tif->tif_rawcc = 0; + res = libdeflate_zlib_decompress(sp->libdeflate_dec, tif->tif_rawcp, + (size_t)tif->tif_rawcc, op, + (size_t)occ, NULL); - /* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */ - /* There are odd files in the wild where the last strip, when */ - /* it is smaller in height than td_rowsperstrip, actually contains */ - /* data for td_rowsperstrip lines. Just ignore that silently. */ - if( res != LIBDEFLATE_SUCCESS && - res != LIBDEFLATE_INSUFFICIENT_SPACE ) - { - TIFFErrorExtR(tif, module, - "Decoding error at scanline %lu", - (unsigned long) tif->tif_row); - return 0; - } + tif->tif_rawcp += tif->tif_rawcc; + tif->tif_rawcc = 0; - return 1; + /* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */ + /* There are odd files in the wild where the last strip, when */ + /* it is smaller in height than td_rowsperstrip, actually contains + */ + /* data for td_rowsperstrip lines. Just ignore that silently. */ + if (res != LIBDEFLATE_SUCCESS && + res != LIBDEFLATE_INSUFFICIENT_SPACE) + { + TIFFErrorExtR(tif, module, "Decoding error at scanline %lu", + (unsigned long)tif->tif_row); + return 0; } - } while(0); - sp->libdeflate_state = 0; + + return 1; + } + } while (0); + sp->libdeflate_state = 0; #endif /* LIBDEFLATE_SUPPORT */ - sp->stream.next_in = tif->tif_rawcp; - - sp->stream.next_out = op; - assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - do { - int state; - uInt avail_in_before = (uint64_t)tif->tif_rawcc <= 0xFFFFFFFFU ? (uInt)tif->tif_rawcc : 0xFFFFFFFFU; - uInt avail_out_before = (uint64_t)occ < 0xFFFFFFFFU ? (uInt) occ : 0xFFFFFFFFU; - sp->stream.avail_in = avail_in_before; - sp->stream.avail_out = avail_out_before; - /* coverity[overrun-buffer-arg] */ - state = inflate(&sp->stream, Z_PARTIAL_FLUSH); - tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in); - occ -= (avail_out_before - sp->stream.avail_out); - if (state == Z_STREAM_END) - break; - if (state == Z_DATA_ERROR) { - TIFFErrorExtR(tif, module, - "Decoding error at scanline %lu, %s", - (unsigned long) tif->tif_row, SAFE_MSG(sp)); - return (0); - } - if (state != Z_OK) { - TIFFErrorExtR(tif, module, - "ZLib error: %s", SAFE_MSG(sp)); - return (0); - } - } while (occ > 0); - if (occ != 0) { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %lu (short %" PRIu64 " bytes)", - (unsigned long) tif->tif_row, (uint64_t) occ); - return (0); - } - - tif->tif_rawcp = sp->stream.next_in; - - return (1); + sp->stream.next_in = tif->tif_rawcp; + + sp->stream.next_out = op; + assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + do + { + int state; + uInt avail_in_before = (uint64_t)tif->tif_rawcc <= 0xFFFFFFFFU + ? (uInt)tif->tif_rawcc + : 0xFFFFFFFFU; + uInt avail_out_before = + (uint64_t)occ < 0xFFFFFFFFU ? (uInt)occ : 0xFFFFFFFFU; + sp->stream.avail_in = avail_in_before; + sp->stream.avail_out = avail_out_before; + /* coverity[overrun-buffer-arg] */ + state = inflate(&sp->stream, Z_PARTIAL_FLUSH); + tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in); + occ -= (avail_out_before - sp->stream.avail_out); + if (state == Z_STREAM_END) + break; + if (state == Z_DATA_ERROR) + { + TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s", + (unsigned long)tif->tif_row, SAFE_MSG(sp)); + return (0); + } + if (state != Z_OK) + { + TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp)); + return (0); + } + } while (occ > 0); + if (occ != 0) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %lu (short %" PRIu64 + " bytes)", + (unsigned long)tif->tif_row, (uint64_t)occ); + return (0); + } + + tif->tif_rawcp = sp->stream.next_in; + + return (1); } -static int -ZIPSetupEncode(TIFF* tif) +static int ZIPSetupEncode(TIFF *tif) { - static const char module[] = "ZIPSetupEncode"; - ZIPState* sp = EncoderState(tif); - int cappedQuality; - - assert(sp != NULL); - if (sp->state & ZSTATE_INIT_DECODE) { - inflateEnd(&sp->stream); - sp->state = 0; - } - - cappedQuality = sp->zipquality; - if( cappedQuality > Z_BEST_COMPRESSION ) - cappedQuality = Z_BEST_COMPRESSION; - - if (deflateInit(&sp->stream, cappedQuality) != Z_OK) { - TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp)); - return (0); - } else { - sp->state |= ZSTATE_INIT_ENCODE; - return (1); - } + static const char module[] = "ZIPSetupEncode"; + ZIPState *sp = EncoderState(tif); + int cappedQuality; + + assert(sp != NULL); + if (sp->state & ZSTATE_INIT_DECODE) + { + inflateEnd(&sp->stream); + sp->state = 0; + } + + cappedQuality = sp->zipquality; + if (cappedQuality > Z_BEST_COMPRESSION) + cappedQuality = Z_BEST_COMPRESSION; + + if (deflateInit(&sp->stream, cappedQuality) != Z_OK) + { + TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp)); + return (0); + } + else + { + sp->state |= ZSTATE_INIT_ENCODE; + return (1); + } } /* * Reset encoding state at the start of a strip. */ -static int -ZIPPreEncode(TIFF* tif, uint16_t s) +static int ZIPPreEncode(TIFF *tif, uint16_t s) { - ZIPState *sp = EncoderState(tif); + ZIPState *sp = EncoderState(tif); - (void) s; - assert(sp != NULL); - if( sp->state != ZSTATE_INIT_ENCODE ) - tif->tif_setupencode( tif ); + (void)s; + assert(sp != NULL); + if (sp->state != ZSTATE_INIT_ENCODE) + tif->tif_setupencode(tif); #if LIBDEFLATE_SUPPORT - sp->libdeflate_state = -1; + sp->libdeflate_state = -1; #endif - sp->stream.next_out = tif->tif_rawdata; - assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU; - return (deflateReset(&sp->stream) == Z_OK); + sp->stream.next_out = tif->tif_rawdata; + assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU + ? (uInt)tif->tif_rawdatasize + : 0xFFFFFFFFU; + return (deflateReset(&sp->stream) == Z_OK); } /* * Encode a chunk of pixels. */ -static int -ZIPEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) +static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "ZIPEncode"; - ZIPState *sp = EncoderState(tif); + static const char module[] = "ZIPEncode"; + ZIPState *sp = EncoderState(tif); - assert(sp != NULL); - assert(sp->state == ZSTATE_INIT_ENCODE); + assert(sp != NULL); + assert(sp->state == ZSTATE_INIT_ENCODE); - (void) s; + (void)s; #if LIBDEFLATE_SUPPORT - if( sp->libdeflate_state == 1 ) - return 0; - - /* If we have libdeflate support and we are asked to write a whole */ - /* strip/tile, then go for using it */ - do { - TIFFDirectory *td = &tif->tif_dir; - - if( sp->libdeflate_state == 0 ) - break; - if( sp->subcodec == DEFLATE_SUBCODEC_ZLIB ) - break; - - /* Libdeflate does not support the 0-compression level */ - if( sp->zipquality == Z_NO_COMPRESSION ) - break; - - /* Check if we are in the situation where we can use libdeflate */ - if (isTiled(tif)) { - if( TIFFTileSize64(tif) != (uint64_t)cc ) - break; - } else { - uint32_t strip_height = td->td_imagelength - tif->tif_row; - if (strip_height > td->td_rowsperstrip) - strip_height = td->td_rowsperstrip; - if( TIFFVStripSize64(tif, strip_height) != (uint64_t)cc ) - break; - } - - /* Check for overflow */ - if( (size_t)tif->tif_rawdatasize != (uint64_t)tif->tif_rawdatasize ) + if (sp->libdeflate_state == 1) + return 0; + + /* If we have libdeflate support and we are asked to write a whole */ + /* strip/tile, then go for using it */ + do + { + TIFFDirectory *td = &tif->tif_dir; + + if (sp->libdeflate_state == 0) + break; + if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB) + break; + + /* Libdeflate does not support the 0-compression level */ + if (sp->zipquality == Z_NO_COMPRESSION) + break; + + /* Check if we are in the situation where we can use libdeflate */ + if (isTiled(tif)) + { + if (TIFFTileSize64(tif) != (uint64_t)cc) break; - if( (size_t)cc != (uint64_t)cc ) + } + else + { + uint32_t strip_height = td->td_imagelength - tif->tif_row; + if (strip_height > td->td_rowsperstrip) + strip_height = td->td_rowsperstrip; + if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc) break; - - /* Go for compression using libdeflate */ + } + + /* Check for overflow */ + if ((size_t)tif->tif_rawdatasize != (uint64_t)tif->tif_rawdatasize) + break; + if ((size_t)cc != (uint64_t)cc) + break; + + /* Go for compression using libdeflate */ + { + size_t nCompressedBytes; + if (sp->libdeflate_enc == NULL) { - size_t nCompressedBytes; - if( sp->libdeflate_enc == NULL ) - { - /* To get results as good as zlib, we asked for an extra */ - /* level of compression */ - sp->libdeflate_enc = libdeflate_alloc_compressor( - sp->zipquality == Z_DEFAULT_COMPRESSION ? 7 : - sp->zipquality >= 6 && sp->zipquality <= 9 ? sp->zipquality + 1 : - sp->zipquality); - if( sp->libdeflate_enc == NULL ) - { - TIFFErrorExtR(tif, module, - "Cannot allocate compressor"); - break; - } - } - - /* Make sure the output buffer is large enough for the worse case. */ - /* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */ - /* we've taken a 10% margin over the uncompressed size, which should */ - /* be large enough even for the the worse case scenario. */ - if( libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) > - (size_t)tif->tif_rawdatasize) + /* To get results as good as zlib, we asked for an extra */ + /* level of compression */ + sp->libdeflate_enc = libdeflate_alloc_compressor( + sp->zipquality == Z_DEFAULT_COMPRESSION ? 7 + : sp->zipquality >= 6 && sp->zipquality <= 9 + ? sp->zipquality + 1 + : sp->zipquality); + if (sp->libdeflate_enc == NULL) { + TIFFErrorExtR(tif, module, "Cannot allocate compressor"); break; } + } - sp->libdeflate_state = 1; - nCompressedBytes = libdeflate_zlib_compress( - sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata, (size_t)tif->tif_rawdatasize); + /* Make sure the output buffer is large enough for the worse case. + */ + /* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */ + /* we've taken a 10% margin over the uncompressed size, which should + */ + /* be large enough even for the the worse case scenario. */ + if (libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) > + (size_t)tif->tif_rawdatasize) + { + break; + } - if( nCompressedBytes == 0 ) - { - TIFFErrorExtR(tif, module, - "Encoder error at scanline %lu", - (unsigned long) tif->tif_row); - return 0; - } + sp->libdeflate_state = 1; + nCompressedBytes = libdeflate_zlib_compress( + sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata, + (size_t)tif->tif_rawdatasize); - tif->tif_rawcc = nCompressedBytes; + if (nCompressedBytes == 0) + { + TIFFErrorExtR(tif, module, "Encoder error at scanline %lu", + (unsigned long)tif->tif_row); + return 0; + } - if( !TIFFFlushData1(tif) ) - return 0; + tif->tif_rawcc = nCompressedBytes; - return 1; - } - } while(0); - sp->libdeflate_state = 0; + if (!TIFFFlushData1(tif)) + return 0; + + return 1; + } + } while (0); + sp->libdeflate_state = 0; #endif /* LIBDEFLATE_SUPPORT */ - sp->stream.next_in = bp; - assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised, - we need to simplify this code to reflect a ZLib that is likely updated - to deal with 8byte memory sizes, though this code will respond - appropriately even before we simplify it */ - do { - uInt avail_in_before = (uint64_t)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU; - sp->stream.avail_in = avail_in_before; - /* coverity[overrun-buffer-arg] */ - if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) { - TIFFErrorExtR(tif, module, - "Encoder error: %s", - SAFE_MSG(sp)); - return (0); - } - if (sp->stream.avail_out == 0) { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU; - } - cc -= (avail_in_before - sp->stream.avail_in); - } while (cc > 0); - return (1); + sp->stream.next_in = bp; + assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised, + we need to simplify this code to reflect a ZLib that is likely updated + to deal with 8byte memory sizes, though this code will respond + appropriately even before we simplify it */ + do + { + uInt avail_in_before = + (uint64_t)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU; + sp->stream.avail_in = avail_in_before; + /* coverity[overrun-buffer-arg] */ + if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) + { + TIFFErrorExtR(tif, module, "Encoder error: %s", SAFE_MSG(sp)); + return (0); + } + if (sp->stream.avail_out == 0) + { + tif->tif_rawcc = tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU + ? (uInt)tif->tif_rawdatasize + : 0xFFFFFFFFU; + } + cc -= (avail_in_before - sp->stream.avail_in); + } while (cc > 0); + return (1); } /* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ -static int -ZIPPostEncode(TIFF* tif) +static int ZIPPostEncode(TIFF *tif) { - static const char module[] = "ZIPPostEncode"; - ZIPState *sp = EncoderState(tif); - int state; + static const char module[] = "ZIPPostEncode"; + ZIPState *sp = EncoderState(tif); + int state; #if LIBDEFLATE_SUPPORT - if( sp->libdeflate_state == 1 ) - return 1; + if (sp->libdeflate_state == 1) + return 1; #endif - sp->stream.avail_in = 0; - do { - state = deflate(&sp->stream, Z_FINISH); - switch (state) { - case Z_STREAM_END: - case Z_OK: - if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) - { - tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out; - if (!TIFFFlushData1(tif)) - return 0; - sp->stream.next_out = tif->tif_rawdata; - sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU ? (uInt)tif->tif_rawdatasize : 0xFFFFFFFFU; - } - break; - default: - TIFFErrorExtR(tif, module, - "ZLib error: %s", SAFE_MSG(sp)); - return (0); - } - } while (state != Z_STREAM_END); - return (1); + sp->stream.avail_in = 0; + do + { + state = deflate(&sp->stream, Z_FINISH); + switch (state) + { + case Z_STREAM_END: + case Z_OK: + if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) + { + tif->tif_rawcc = + tif->tif_rawdatasize - sp->stream.avail_out; + if (!TIFFFlushData1(tif)) + return 0; + sp->stream.next_out = tif->tif_rawdata; + sp->stream.avail_out = + (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU + ? (uInt)tif->tif_rawdatasize + : 0xFFFFFFFFU; + } + break; + default: + TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp)); + return (0); + } + } while (state != Z_STREAM_END); + return (1); } -static void -ZIPCleanup(TIFF* tif) +static void ZIPCleanup(TIFF *tif) { - ZIPState* sp = ZState(tif); + ZIPState *sp = ZState(tif); - assert(sp != 0); + assert(sp != 0); - (void)TIFFPredictorCleanup(tif); + (void)TIFFPredictorCleanup(tif); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; - if (sp->state & ZSTATE_INIT_ENCODE) { - deflateEnd(&sp->stream); - sp->state = 0; - } else if( sp->state & ZSTATE_INIT_DECODE) { - inflateEnd(&sp->stream); - sp->state = 0; - } + if (sp->state & ZSTATE_INIT_ENCODE) + { + deflateEnd(&sp->stream); + sp->state = 0; + } + else if (sp->state & ZSTATE_INIT_DECODE) + { + inflateEnd(&sp->stream); + sp->state = 0; + } #if LIBDEFLATE_SUPPORT - if( sp->libdeflate_dec ) - libdeflate_free_decompressor(sp->libdeflate_dec); - if( sp->libdeflate_enc ) - libdeflate_free_compressor(sp->libdeflate_enc); + if (sp->libdeflate_dec) + libdeflate_free_decompressor(sp->libdeflate_dec); + if (sp->libdeflate_enc) + libdeflate_free_compressor(sp->libdeflate_enc); #endif - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } -static int -ZIPVSetField(TIFF* tif, uint32_t tag, va_list ap) +static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[] = "ZIPVSetField"; - ZIPState* sp = ZState(tif); - - switch (tag) { - case TIFFTAG_ZIPQUALITY: - sp->zipquality = (int) va_arg(ap, int); - if( sp->zipquality < Z_DEFAULT_COMPRESSION || - sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL ) { - TIFFErrorExtR(tif, module, - "Invalid ZipQuality value. Should be in [-1,%d] range", - LIBDEFLATE_MAX_COMPRESSION_LEVEL); - return 0; - } - - if ( sp->state&ZSTATE_INIT_ENCODE ) { - int cappedQuality = sp->zipquality; - if( cappedQuality > Z_BEST_COMPRESSION ) - cappedQuality = Z_BEST_COMPRESSION; - if (deflateParams(&sp->stream, - cappedQuality, Z_DEFAULT_STRATEGY) != Z_OK) { - TIFFErrorExtR(tif, module, "ZLib error: %s", - SAFE_MSG(sp)); - return (0); - } - } + static const char module[] = "ZIPVSetField"; + ZIPState *sp = ZState(tif); + + switch (tag) + { + case TIFFTAG_ZIPQUALITY: + sp->zipquality = (int)va_arg(ap, int); + if (sp->zipquality < Z_DEFAULT_COMPRESSION || + sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL) + { + TIFFErrorExtR( + tif, module, + "Invalid ZipQuality value. Should be in [-1,%d] range", + LIBDEFLATE_MAX_COMPRESSION_LEVEL); + return 0; + } -#if LIBDEFLATE_SUPPORT - if( sp->libdeflate_enc ) + if (sp->state & ZSTATE_INIT_ENCODE) + { + int cappedQuality = sp->zipquality; + if (cappedQuality > Z_BEST_COMPRESSION) + cappedQuality = Z_BEST_COMPRESSION; + if (deflateParams(&sp->stream, cappedQuality, + Z_DEFAULT_STRATEGY) != Z_OK) { - libdeflate_free_compressor(sp->libdeflate_enc); - sp->libdeflate_enc = NULL; + TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp)); + return (0); } + } + +#if LIBDEFLATE_SUPPORT + if (sp->libdeflate_enc) + { + libdeflate_free_compressor(sp->libdeflate_enc); + sp->libdeflate_enc = NULL; + } #endif - return (1); + return (1); case TIFFTAG_DEFLATE_SUBCODEC: - sp->subcodec = (int) va_arg(ap, int); - if( sp->subcodec != DEFLATE_SUBCODEC_ZLIB && - sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE ) - { - TIFFErrorExtR(tif, module, - "Invalid DeflateCodec value."); - return 0; - } + sp->subcodec = (int)va_arg(ap, int); + if (sp->subcodec != DEFLATE_SUBCODEC_ZLIB && + sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE) + { + TIFFErrorExtR(tif, module, "Invalid DeflateCodec value."); + return 0; + } #if !LIBDEFLATE_SUPPORT - if( sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE ) - { - TIFFErrorExtR(tif, module, - "DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE unsupported in this build"); - return 0; - } + if (sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE) + { + TIFFErrorExtR(tif, module, + "DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE " + "unsupported in this build"); + return 0; + } #endif - return 1; + return 1; - default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ + default: + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ } -static int -ZIPVGetField(TIFF* tif, uint32_t tag, va_list ap) +static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap) { - ZIPState* sp = ZState(tif); + ZIPState *sp = ZState(tif); - switch (tag) { - case TIFFTAG_ZIPQUALITY: - *va_arg(ap, int*) = sp->zipquality; - break; + switch (tag) + { + case TIFFTAG_ZIPQUALITY: + *va_arg(ap, int *) = sp->zipquality; + break; case TIFFTAG_DEFLATE_SUBCODEC: - *va_arg(ap, int*) = sp->subcodec; - break; + *va_arg(ap, int *) = sp->subcodec; + break; - default: - return (*sp->vgetparent)(tif, tag, ap); - } - return (1); + default: + return (*sp->vgetparent)(tif, tag, ap); + } + return (1); } static const TIFFField zipFields[] = { - { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, - { TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL }, + {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, + {TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL}, }; -int -TIFFInitZIP(TIFF* tif, int scheme) +int TIFFInitZIP(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitZIP"; - ZIPState* sp; + static const char module[] = "TIFFInitZIP"; + ZIPState *sp; - assert( (scheme == COMPRESSION_DEFLATE) - || (scheme == COMPRESSION_ADOBE_DEFLATE)); + assert((scheme == COMPRESSION_DEFLATE) || + (scheme == COMPRESSION_ADOBE_DEFLATE)); #ifdef NDEBUG - (void)scheme; + (void)scheme; #endif - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) { - TIFFErrorExtR(tif, module, - "Merging Deflate codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t*) _TIFFcallocExt(tif, sizeof (ZIPState), 1); - if (tif->tif_data == NULL) - goto bad; - sp = ZState(tif); - sp->stream.zalloc = NULL; - sp->stream.zfree = NULL; - sp->stream.opaque = NULL; - sp->stream.data_type = Z_BINARY; - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ - sp->state = 0; + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) + { + TIFFErrorExtR(tif, module, + "Merging Deflate codec-specific tags failed"); + return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, sizeof(ZIPState), 1); + if (tif->tif_data == NULL) + goto bad; + sp = ZState(tif); + sp->stream.zalloc = NULL; + sp->stream.zfree = NULL; + sp->stream.opaque = NULL; + sp->stream.data_type = Z_BINARY; + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */ + sp->state = 0; #if LIBDEFLATE_SUPPORT - sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE; + sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE; #else - sp->subcodec = DEFLATE_SUBCODEC_ZLIB; + sp->subcodec = DEFLATE_SUBCODEC_ZLIB; #endif - /* - * Install codec methods. - */ - tif->tif_fixuptags = ZIPFixupTags; - tif->tif_setupdecode = ZIPSetupDecode; - tif->tif_predecode = ZIPPreDecode; - tif->tif_decoderow = ZIPDecode; - tif->tif_decodestrip = ZIPDecode; - tif->tif_decodetile = ZIPDecode; - tif->tif_setupencode = ZIPSetupEncode; - tif->tif_preencode = ZIPPreEncode; - tif->tif_postencode = ZIPPostEncode; - tif->tif_encoderow = ZIPEncode; - tif->tif_encodestrip = ZIPEncode; - tif->tif_encodetile = ZIPEncode; - tif->tif_cleanup = ZIPCleanup; - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); - return (1); + /* + * Install codec methods. + */ + tif->tif_fixuptags = ZIPFixupTags; + tif->tif_setupdecode = ZIPSetupDecode; + tif->tif_predecode = ZIPPreDecode; + tif->tif_decoderow = ZIPDecode; + tif->tif_decodestrip = ZIPDecode; + tif->tif_decodetile = ZIPDecode; + tif->tif_setupencode = ZIPSetupEncode; + tif->tif_preencode = ZIPPreEncode; + tif->tif_postencode = ZIPPostEncode; + tif->tif_encoderow = ZIPEncode; + tif->tif_encodestrip = ZIPEncode; + tif->tif_encodetile = ZIPEncode; + tif->tif_cleanup = ZIPCleanup; + /* + * Setup predictor setup. + */ + (void)TIFFPredictorInit(tif); + return (1); bad: - TIFFErrorExtR(tif, module, - "No space for ZIP state block"); - return (0); + TIFFErrorExtR(tif, module, "No space for ZIP state block"); + return (0); } #endif /* ZIP_SUPPORT */ diff --git a/libtiff/tif_zstd.c b/libtiff/tif_zstd.c index 30a848af..64699310 100644 --- a/libtiff/tif_zstd.c +++ b/libtiff/tif_zstd.c @@ -1,35 +1,35 @@ /* -* Copyright (c) 2017, Planet Labs -* Author: <even.rouault at spatialys.com> -* -* Permission to use, copy, modify, distribute, and sell this software and -* its documentation for any purpose is hereby granted without fee, provided -* that (i) the above copyright notices and this permission notice appear in -* all copies of the software and related documentation, and (ii) the names of -* Sam Leffler and Silicon Graphics may not be used in any advertising or -* publicity relating to the software without the specific, prior written -* permission of Sam Leffler and Silicon Graphics. -* -* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. -* -* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR -* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, -* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF -* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -* OF THIS SOFTWARE. -*/ + * Copyright (c) 2017, Planet Labs + * Author: <even.rouault at spatialys.com> + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ #include "tiffiop.h" #ifdef ZSTD_SUPPORT /* -* TIFF Library. -* -* ZSTD Compression Support -* -*/ + * TIFF Library. + * + * ZSTD Compression Support + * + */ #include "tif_predict.h" #include "zstd.h" @@ -37,401 +37,400 @@ #include <stdio.h> /* -* State block for each open TIFF file using ZSTD compression/decompression. -*/ -typedef struct { - TIFFPredictorState predict; - ZSTD_DStream* dstream; - ZSTD_CStream* cstream; - int compression_level; /* compression level */ - ZSTD_outBuffer out_buffer; - int state; /* state flags */ + * State block for each open TIFF file using ZSTD compression/decompression. + */ +typedef struct +{ + TIFFPredictorState predict; + ZSTD_DStream *dstream; + ZSTD_CStream *cstream; + int compression_level; /* compression level */ + ZSTD_outBuffer out_buffer; + int state; /* state flags */ #define LSTATE_INIT_DECODE 0x01 #define LSTATE_INIT_ENCODE 0x02 - TIFFVGetMethod vgetparent; /* super-class method */ - TIFFVSetMethod vsetparent; /* super-class method */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ } ZSTDState; -#define LState(tif) ((ZSTDState*) (tif)->tif_data) -#define DecoderState(tif) LState(tif) -#define EncoderState(tif) LState(tif) +#define LState(tif) ((ZSTDState *)(tif)->tif_data) +#define DecoderState(tif) LState(tif) +#define EncoderState(tif) LState(tif) -static int ZSTDEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s); -static int ZSTDDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s); +static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s); +static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s); -static int -ZSTDFixupTags(TIFF* tif) +static int ZSTDFixupTags(TIFF *tif) { - (void) tif; - return 1; + (void)tif; + return 1; } -static int -ZSTDSetupDecode(TIFF* tif) +static int ZSTDSetupDecode(TIFF *tif) { - ZSTDState* sp = DecoderState(tif); + ZSTDState *sp = DecoderState(tif); - assert(sp != NULL); + assert(sp != NULL); - /* if we were last encoding, terminate this mode */ - if (sp->state & LSTATE_INIT_ENCODE) { - ZSTD_freeCStream(sp->cstream); - sp->cstream = NULL; - sp->state = 0; - } + /* if we were last encoding, terminate this mode */ + if (sp->state & LSTATE_INIT_ENCODE) + { + ZSTD_freeCStream(sp->cstream); + sp->cstream = NULL; + sp->state = 0; + } - sp->state |= LSTATE_INIT_DECODE; - return 1; + sp->state |= LSTATE_INIT_DECODE; + return 1; } /* -* Setup state for decoding a strip. -*/ -static int -ZSTDPreDecode(TIFF* tif, uint16_t s) + * Setup state for decoding a strip. + */ +static int ZSTDPreDecode(TIFF *tif, uint16_t s) { - static const char module[] = "ZSTDPreDecode"; - ZSTDState* sp = DecoderState(tif); - size_t zstd_ret; + static const char module[] = "ZSTDPreDecode"; + ZSTDState *sp = DecoderState(tif); + size_t zstd_ret; - (void) s; - assert(sp != NULL); + (void)s; + assert(sp != NULL); - if( (sp->state & LSTATE_INIT_DECODE) == 0 ) - tif->tif_setupdecode(tif); + if ((sp->state & LSTATE_INIT_DECODE) == 0) + tif->tif_setupdecode(tif); - if( sp->dstream == NULL ) + if (sp->dstream == NULL) + { + sp->dstream = ZSTD_createDStream(); + if (sp->dstream == NULL) { - sp->dstream = ZSTD_createDStream(); - if( sp->dstream == NULL ) { - TIFFErrorExtR(tif, module, - "Cannot allocate decompression stream"); - return 0; - } - } - - zstd_ret = ZSTD_initDStream(sp->dstream); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExtR(tif, module, - "Error in ZSTD_initDStream(): %s", - ZSTD_getErrorName(zstd_ret)); + TIFFErrorExtR(tif, module, "Cannot allocate decompression stream"); return 0; } + } - return 1; + zstd_ret = ZSTD_initDStream(sp->dstream); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_initDStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + + return 1; } -static int -ZSTDDecode(TIFF* tif, uint8_t* op, tmsize_t occ, uint16_t s) +static int ZSTDDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s) { - static const char module[] = "ZSTDDecode"; - ZSTDState* sp = DecoderState(tif); - ZSTD_inBuffer in_buffer; - ZSTD_outBuffer out_buffer; - size_t zstd_ret; - - (void) s; - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_DECODE); - - in_buffer.src = tif->tif_rawcp; - in_buffer.size = (size_t) tif->tif_rawcc; - in_buffer.pos = 0; - - out_buffer.dst = op; - out_buffer.size = (size_t) occ; - out_buffer.pos = 0; - - do { - zstd_ret = ZSTD_decompressStream(sp->dstream, &out_buffer, - &in_buffer); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExtR(tif, module, - "Error in ZSTD_decompressStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - } while( zstd_ret != 0 && - in_buffer.pos < in_buffer.size && - out_buffer.pos < out_buffer.size ); - - if (out_buffer.pos < (size_t)occ) { - TIFFErrorExtR(tif, module, - "Not enough data at scanline %lu (short %lu bytes)", - (unsigned long) tif->tif_row, - (unsigned long) ((size_t)occ - out_buffer.pos)); - return 0; + static const char module[] = "ZSTDDecode"; + ZSTDState *sp = DecoderState(tif); + ZSTD_inBuffer in_buffer; + ZSTD_outBuffer out_buffer; + size_t zstd_ret; + + (void)s; + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_DECODE); + + in_buffer.src = tif->tif_rawcp; + in_buffer.size = (size_t)tif->tif_rawcc; + in_buffer.pos = 0; + + out_buffer.dst = op; + out_buffer.size = (size_t)occ; + out_buffer.pos = 0; + + do + { + zstd_ret = ZSTD_decompressStream(sp->dstream, &out_buffer, &in_buffer); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_decompressStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; } + } while (zstd_ret != 0 && in_buffer.pos < in_buffer.size && + out_buffer.pos < out_buffer.size); - tif->tif_rawcp += in_buffer.pos; - tif->tif_rawcc -= in_buffer.pos; + if (out_buffer.pos < (size_t)occ) + { + TIFFErrorExtR(tif, module, + "Not enough data at scanline %lu (short %lu bytes)", + (unsigned long)tif->tif_row, + (unsigned long)((size_t)occ - out_buffer.pos)); + return 0; + } - return 1; + tif->tif_rawcp += in_buffer.pos; + tif->tif_rawcc -= in_buffer.pos; + + return 1; } -static int -ZSTDSetupEncode(TIFF* tif) +static int ZSTDSetupEncode(TIFF *tif) { - ZSTDState* sp = EncoderState(tif); + ZSTDState *sp = EncoderState(tif); - assert(sp != NULL); - if (sp->state & LSTATE_INIT_DECODE) { - ZSTD_freeDStream(sp->dstream); - sp->dstream = NULL; - sp->state = 0; - } + assert(sp != NULL); + if (sp->state & LSTATE_INIT_DECODE) + { + ZSTD_freeDStream(sp->dstream); + sp->dstream = NULL; + sp->state = 0; + } - sp->state |= LSTATE_INIT_ENCODE; - return 1; + sp->state |= LSTATE_INIT_ENCODE; + return 1; } /* -* Reset encoding state at the start of a strip. -*/ -static int -ZSTDPreEncode(TIFF* tif, uint16_t s) + * Reset encoding state at the start of a strip. + */ +static int ZSTDPreEncode(TIFF *tif, uint16_t s) { - static const char module[] = "ZSTDPreEncode"; - ZSTDState *sp = EncoderState(tif); - size_t zstd_ret; - - (void) s; - assert(sp != NULL); - if( sp->state != LSTATE_INIT_ENCODE ) - tif->tif_setupencode(tif); - - if (sp->cstream == NULL) { - sp->cstream = ZSTD_createCStream(); - if( sp->cstream == NULL ) { - TIFFErrorExtR(tif, module, - "Cannot allocate compression stream"); - return 0; - } - } - - zstd_ret = ZSTD_initCStream(sp->cstream, sp->compression_level); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExtR(tif, module, - "Error in ZSTD_initCStream(): %s", - ZSTD_getErrorName(zstd_ret)); + static const char module[] = "ZSTDPreEncode"; + ZSTDState *sp = EncoderState(tif); + size_t zstd_ret; + + (void)s; + assert(sp != NULL); + if (sp->state != LSTATE_INIT_ENCODE) + tif->tif_setupencode(tif); + + if (sp->cstream == NULL) + { + sp->cstream = ZSTD_createCStream(); + if (sp->cstream == NULL) + { + TIFFErrorExtR(tif, module, "Cannot allocate compression stream"); return 0; } + } + + zstd_ret = ZSTD_initCStream(sp->cstream, sp->compression_level); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_initCStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } - sp->out_buffer.dst = tif->tif_rawdata; - sp->out_buffer.size = (size_t)tif->tif_rawdatasize; - sp->out_buffer.pos = 0; + sp->out_buffer.dst = tif->tif_rawdata; + sp->out_buffer.size = (size_t)tif->tif_rawdatasize; + sp->out_buffer.pos = 0; - return 1; + return 1; } /* -* Encode a chunk of pixels. -*/ -static int -ZSTDEncode(TIFF* tif, uint8_t* bp, tmsize_t cc, uint16_t s) + * Encode a chunk of pixels. + */ +static int ZSTDEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s) { - static const char module[] = "ZSTDEncode"; - ZSTDState *sp = EncoderState(tif); - ZSTD_inBuffer in_buffer; - size_t zstd_ret; - - assert(sp != NULL); - assert(sp->state == LSTATE_INIT_ENCODE); - - (void) s; - - in_buffer.src = bp; - in_buffer.size = (size_t)cc; - in_buffer.pos = 0; - - do { - zstd_ret = ZSTD_compressStream(sp->cstream, &sp->out_buffer, - &in_buffer); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExtR(tif, module, - "Error in ZSTD_compressStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - if( sp->out_buffer.pos == sp->out_buffer.size ) { - tif->tif_rawcc = tif->tif_rawdatasize; - if (!TIFFFlushData1(tif)) - return 0; - sp->out_buffer.dst = tif->tif_rawcp; - sp->out_buffer.pos = 0; - } - } while( in_buffer.pos < in_buffer.size ); - - return 1; + static const char module[] = "ZSTDEncode"; + ZSTDState *sp = EncoderState(tif); + ZSTD_inBuffer in_buffer; + size_t zstd_ret; + + assert(sp != NULL); + assert(sp->state == LSTATE_INIT_ENCODE); + + (void)s; + + in_buffer.src = bp; + in_buffer.size = (size_t)cc; + in_buffer.pos = 0; + + do + { + zstd_ret = + ZSTD_compressStream(sp->cstream, &sp->out_buffer, &in_buffer); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_compressStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + if (sp->out_buffer.pos == sp->out_buffer.size) + { + tif->tif_rawcc = tif->tif_rawdatasize; + if (!TIFFFlushData1(tif)) + return 0; + sp->out_buffer.dst = tif->tif_rawcp; + sp->out_buffer.pos = 0; + } + } while (in_buffer.pos < in_buffer.size); + + return 1; } /* -* Finish off an encoded strip by flushing it. -*/ -static int -ZSTDPostEncode(TIFF* tif) + * Finish off an encoded strip by flushing it. + */ +static int ZSTDPostEncode(TIFF *tif) { - static const char module[] = "ZSTDPostEncode"; - ZSTDState *sp = EncoderState(tif); - size_t zstd_ret; - - do { - zstd_ret = ZSTD_endStream(sp->cstream, &sp->out_buffer); - if( ZSTD_isError(zstd_ret) ) { - TIFFErrorExtR(tif, module, - "Error in ZSTD_endStream(): %s", - ZSTD_getErrorName(zstd_ret)); - return 0; - } - if( sp->out_buffer.pos > 0 ) { - tif->tif_rawcc = sp->out_buffer.pos; - if (!TIFFFlushData1(tif)) - return 0; - sp->out_buffer.dst = tif->tif_rawcp; - sp->out_buffer.pos = 0; - } - } while (zstd_ret != 0); - return 1; + static const char module[] = "ZSTDPostEncode"; + ZSTDState *sp = EncoderState(tif); + size_t zstd_ret; + + do + { + zstd_ret = ZSTD_endStream(sp->cstream, &sp->out_buffer); + if (ZSTD_isError(zstd_ret)) + { + TIFFErrorExtR(tif, module, "Error in ZSTD_endStream(): %s", + ZSTD_getErrorName(zstd_ret)); + return 0; + } + if (sp->out_buffer.pos > 0) + { + tif->tif_rawcc = sp->out_buffer.pos; + if (!TIFFFlushData1(tif)) + return 0; + sp->out_buffer.dst = tif->tif_rawcp; + sp->out_buffer.pos = 0; + } + } while (zstd_ret != 0); + return 1; } -static void -ZSTDCleanup(TIFF* tif) +static void ZSTDCleanup(TIFF *tif) { - ZSTDState* sp = LState(tif); + ZSTDState *sp = LState(tif); - assert(sp != 0); + assert(sp != 0); - (void)TIFFPredictorCleanup(tif); + (void)TIFFPredictorCleanup(tif); - tif->tif_tagmethods.vgetfield = sp->vgetparent; - tif->tif_tagmethods.vsetfield = sp->vsetparent; + tif->tif_tagmethods.vgetfield = sp->vgetparent; + tif->tif_tagmethods.vsetfield = sp->vsetparent; - if (sp->dstream) { - ZSTD_freeDStream(sp->dstream); - sp->dstream = NULL; - } - if (sp->cstream) { - ZSTD_freeCStream(sp->cstream); - sp->cstream = NULL; - } - _TIFFfreeExt(tif, sp); - tif->tif_data = NULL; + if (sp->dstream) + { + ZSTD_freeDStream(sp->dstream); + sp->dstream = NULL; + } + if (sp->cstream) + { + ZSTD_freeCStream(sp->cstream); + sp->cstream = NULL; + } + _TIFFfreeExt(tif, sp); + tif->tif_data = NULL; - _TIFFSetDefaultCompressionState(tif); + _TIFFSetDefaultCompressionState(tif); } -static int -ZSTDVSetField(TIFF* tif, uint32_t tag, va_list ap) +static int ZSTDVSetField(TIFF *tif, uint32_t tag, va_list ap) { - static const char module[] = "ZSTDVSetField"; - ZSTDState* sp = LState(tif); + static const char module[] = "ZSTDVSetField"; + ZSTDState *sp = LState(tif); - switch (tag) { + switch (tag) + { case TIFFTAG_ZSTD_LEVEL: - sp->compression_level = (int) va_arg(ap, int); - if( sp->compression_level <= 0 || - sp->compression_level > ZSTD_maxCLevel() ) - { - TIFFWarningExtR(tif, module, - "ZSTD_LEVEL should be between 1 and %d", - ZSTD_maxCLevel()); - } - return 1; + sp->compression_level = (int)va_arg(ap, int); + if (sp->compression_level <= 0 || + sp->compression_level > ZSTD_maxCLevel()) + { + TIFFWarningExtR(tif, module, + "ZSTD_LEVEL should be between 1 and %d", + ZSTD_maxCLevel()); + } + return 1; default: - return (*sp->vsetparent)(tif, tag, ap); - } - /*NOTREACHED*/ + return (*sp->vsetparent)(tif, tag, ap); + } + /*NOTREACHED*/ } -static int -ZSTDVGetField(TIFF* tif, uint32_t tag, va_list ap) +static int ZSTDVGetField(TIFF *tif, uint32_t tag, va_list ap) { - ZSTDState* sp = LState(tif); + ZSTDState *sp = LState(tif); - switch (tag) { + switch (tag) + { case TIFFTAG_ZSTD_LEVEL: - *va_arg(ap, int*) = sp->compression_level; - break; + *va_arg(ap, int *) = sp->compression_level; + break; default: - return (*sp->vgetparent)(tif, tag, ap); - } - return 1; + return (*sp->vgetparent)(tif, tag, ap); + } + return 1; } static const TIFFField ZSTDFields[] = { - { TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, - TIFF_SETGET_UNDEFINED, - FIELD_PSEUDO, TRUE, FALSE, "ZSTD compression_level", NULL }, + {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, + TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "ZSTD compression_level", + NULL}, }; -int -TIFFInitZSTD(TIFF* tif, int scheme) +int TIFFInitZSTD(TIFF *tif, int scheme) { - static const char module[] = "TIFFInitZSTD"; - ZSTDState* sp; - - (void) scheme; - assert( scheme == COMPRESSION_ZSTD ); - - /* - * Merge codec-specific tag information. - */ - if (!_TIFFMergeFields(tif, ZSTDFields, TIFFArrayCount(ZSTDFields))) { - TIFFErrorExtR(tif, module, - "Merging ZSTD codec-specific tags failed"); - return 0; - } - - /* - * Allocate state block so tag methods have storage to record values. - */ - tif->tif_data = (uint8_t*) _TIFFmallocExt(tif, sizeof(ZSTDState)); - if (tif->tif_data == NULL) - goto bad; - sp = LState(tif); - - /* - * Override parent get/set field methods. - */ - sp->vgetparent = tif->tif_tagmethods.vgetfield; - tif->tif_tagmethods.vgetfield = ZSTDVGetField; /* hook for codec tags */ - sp->vsetparent = tif->tif_tagmethods.vsetfield; - tif->tif_tagmethods.vsetfield = ZSTDVSetField; /* hook for codec tags */ - - /* Default values for codec-specific fields */ - sp->compression_level = 9; /* default comp. level */ - sp->state = 0; - sp->dstream = 0; - sp->cstream = 0; - sp->out_buffer.dst = NULL; - sp->out_buffer.size = 0; - sp->out_buffer.pos = 0; - - /* - * Install codec methods. - */ - tif->tif_fixuptags = ZSTDFixupTags; - tif->tif_setupdecode = ZSTDSetupDecode; - tif->tif_predecode = ZSTDPreDecode; - tif->tif_decoderow = ZSTDDecode; - tif->tif_decodestrip = ZSTDDecode; - tif->tif_decodetile = ZSTDDecode; - tif->tif_setupencode = ZSTDSetupEncode; - tif->tif_preencode = ZSTDPreEncode; - tif->tif_postencode = ZSTDPostEncode; - tif->tif_encoderow = ZSTDEncode; - tif->tif_encodestrip = ZSTDEncode; - tif->tif_encodetile = ZSTDEncode; - tif->tif_cleanup = ZSTDCleanup; - /* - * Setup predictor setup. - */ - (void) TIFFPredictorInit(tif); - return 1; -bad: - TIFFErrorExtR(tif, module, - "No space for ZSTD state block"); + static const char module[] = "TIFFInitZSTD"; + ZSTDState *sp; + + (void)scheme; + assert(scheme == COMPRESSION_ZSTD); + + /* + * Merge codec-specific tag information. + */ + if (!_TIFFMergeFields(tif, ZSTDFields, TIFFArrayCount(ZSTDFields))) + { + TIFFErrorExtR(tif, module, "Merging ZSTD codec-specific tags failed"); return 0; + } + + /* + * Allocate state block so tag methods have storage to record values. + */ + tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(ZSTDState)); + if (tif->tif_data == NULL) + goto bad; + sp = LState(tif); + + /* + * Override parent get/set field methods. + */ + sp->vgetparent = tif->tif_tagmethods.vgetfield; + tif->tif_tagmethods.vgetfield = ZSTDVGetField; /* hook for codec tags */ + sp->vsetparent = tif->tif_tagmethods.vsetfield; + tif->tif_tagmethods.vsetfield = ZSTDVSetField; /* hook for codec tags */ + + /* Default values for codec-specific fields */ + sp->compression_level = 9; /* default comp. level */ + sp->state = 0; + sp->dstream = 0; + sp->cstream = 0; + sp->out_buffer.dst = NULL; + sp->out_buffer.size = 0; + sp->out_buffer.pos = 0; + + /* + * Install codec methods. + */ + tif->tif_fixuptags = ZSTDFixupTags; + tif->tif_setupdecode = ZSTDSetupDecode; + tif->tif_predecode = ZSTDPreDecode; + tif->tif_decoderow = ZSTDDecode; + tif->tif_decodestrip = ZSTDDecode; + tif->tif_decodetile = ZSTDDecode; + tif->tif_setupencode = ZSTDSetupEncode; + tif->tif_preencode = ZSTDPreEncode; + tif->tif_postencode = ZSTDPostEncode; + tif->tif_encoderow = ZSTDEncode; + tif->tif_encodestrip = ZSTDEncode; + tif->tif_encodetile = ZSTDEncode; + tif->tif_cleanup = ZSTDCleanup; + /* + * Setup predictor setup. + */ + (void)TIFFPredictorInit(tif); + return 1; +bad: + TIFFErrorExtR(tif, module, "No space for ZSTD state block"); + return 0; } #endif /* ZSTD_SUPPORT */ diff --git a/libtiff/tiff.h b/libtiff/tiff.h index ab10c162..285a968a 100644 --- a/libtiff/tiff.h +++ b/libtiff/tiff.h @@ -2,28 +2,28 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _TIFF_ -#define _TIFF_ +#define _TIFF_ #include "tiffconf.h" @@ -48,10 +48,10 @@ #define TIFF_VERSION_CLASSIC 42 #define TIFF_VERSION_BIG 43 -#define TIFF_BIGENDIAN 0x4d4d -#define TIFF_LITTLEENDIAN 0x4949 -#define MDI_LITTLEENDIAN 0x5045 -#define MDI_BIGENDIAN 0x4550 +#define TIFF_BIGENDIAN 0x4d4d +#define TIFF_LITTLEENDIAN 0x4949 +#define MDI_LITTLEENDIAN 0x5045 +#define MDI_BIGENDIAN 0x4550 /* * Intrinsic data types required by the file format: @@ -68,26 +68,27 @@ #define TIFF_GCC_DEPRECATED #endif #ifdef _MSC_VER -#define TIFF_MSC_DEPRECATED __declspec(deprecated("libtiff type deprecated; please use corresponding C99 stdint.h type")) +#define TIFF_MSC_DEPRECATED \ + __declspec(deprecated("libtiff type deprecated; please use corresponding " \ + "C99 stdint.h type")) #else #define TIFF_MSC_DEPRECATED #endif #ifndef TIFF_DISABLE_DEPRECATED -typedef TIFF_MSC_DEPRECATED int8_t int8 TIFF_GCC_DEPRECATED; -typedef TIFF_MSC_DEPRECATED uint8_t uint8 TIFF_GCC_DEPRECATED; +typedef TIFF_MSC_DEPRECATED int8_t int8 TIFF_GCC_DEPRECATED; +typedef TIFF_MSC_DEPRECATED uint8_t uint8 TIFF_GCC_DEPRECATED; -typedef TIFF_MSC_DEPRECATED int16_t int16 TIFF_GCC_DEPRECATED; +typedef TIFF_MSC_DEPRECATED int16_t int16 TIFF_GCC_DEPRECATED; typedef TIFF_MSC_DEPRECATED uint16_t uint16 TIFF_GCC_DEPRECATED; -typedef TIFF_MSC_DEPRECATED int32_t int32 TIFF_GCC_DEPRECATED; +typedef TIFF_MSC_DEPRECATED int32_t int32 TIFF_GCC_DEPRECATED; typedef TIFF_MSC_DEPRECATED uint32_t uint32 TIFF_GCC_DEPRECATED; -typedef TIFF_MSC_DEPRECATED int64_t int64 TIFF_GCC_DEPRECATED; +typedef TIFF_MSC_DEPRECATED int64_t int64 TIFF_GCC_DEPRECATED; typedef TIFF_MSC_DEPRECATED uint64_t uint64 TIFF_GCC_DEPRECATED; #endif /* TIFF_DISABLE_DEPRECATED */ - /* * Some types as promoted in a variable argument list * We use uint16_vap rather then directly using int, because this way @@ -101,24 +102,26 @@ typedef int uint16_vap; /* * TIFF header. */ -typedef struct { - uint16_t tiff_magic; /* magic number (defines byte order) */ - uint16_t tiff_version; /* TIFF version number */ +typedef struct +{ + uint16_t tiff_magic; /* magic number (defines byte order) */ + uint16_t tiff_version; /* TIFF version number */ } TIFFHeaderCommon; -typedef struct { - uint16_t tiff_magic; /* magic number (defines byte order) */ - uint16_t tiff_version; /* TIFF version number */ - uint32_t tiff_diroff; /* byte offset to first directory */ +typedef struct +{ + uint16_t tiff_magic; /* magic number (defines byte order) */ + uint16_t tiff_version; /* TIFF version number */ + uint32_t tiff_diroff; /* byte offset to first directory */ } TIFFHeaderClassic; -typedef struct { - uint16_t tiff_magic; /* magic number (defines byte order) */ - uint16_t tiff_version; /* TIFF version number */ - uint16_t tiff_offsetsize; /* size of offsets, should be 8 */ - uint16_t tiff_unused; /* unused word, should be 0 */ - uint64_t tiff_diroff; /* byte offset to first directory */ +typedef struct +{ + uint16_t tiff_magic; /* magic number (defines byte order) */ + uint16_t tiff_version; /* TIFF version number */ + uint16_t tiff_offsetsize; /* size of offsets, should be 8 */ + uint16_t tiff_unused; /* unused word, should be 0 */ + uint64_t tiff_diroff; /* byte offset to first directory */ } TIFFHeaderBig; - /* * NB: In the comments below, * - items marked with a + are obsoleted by revision 5.0, @@ -133,465 +136,544 @@ typedef struct { * * Note: RATIONALs are the ratio of two 32-bit integer values. *--: - * Note2: TIFF_IFD8 data type is used in tiffFields[]-tag definition in order to distinguish the write-handling - of those tags between ClassicTIFF and BigTiff: - For ClassicTIFF libtiff writes a 32-bit value and the TIFF_IFD type-id into the file - For BigTIFF libtiff writes a 64-bit value and the TIFF_IFD8 type-id into the file + * Note2: TIFF_IFD8 data type is used in tiffFields[]-tag definition in order to + distinguish the write-handling of those tags between ClassicTIFF and BigTiff: + For ClassicTIFF libtiff writes a 32-bit value and the TIFF_IFD + type-id into the file For BigTIFF libtiff writes a 64-bit value and the + TIFF_IFD8 type-id into the file */ -typedef enum { - TIFF_NOTYPE = 0, /* placeholder */ - TIFF_BYTE = 1, /* 8-bit unsigned integer */ - TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ - TIFF_SHORT = 3, /* 16-bit unsigned integer */ - TIFF_LONG = 4, /* 32-bit unsigned integer */ - TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ - TIFF_SBYTE = 6, /* !8-bit signed integer */ - TIFF_UNDEFINED = 7, /* !8-bit untyped data */ - TIFF_SSHORT = 8, /* !16-bit signed integer */ - TIFF_SLONG = 9, /* !32-bit signed integer */ - TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ - TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ - TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ - TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */ - TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */ - TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */ - TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */ +typedef enum +{ + TIFF_NOTYPE = 0, /* placeholder */ + TIFF_BYTE = 1, /* 8-bit unsigned integer */ + TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ + TIFF_SHORT = 3, /* 16-bit unsigned integer */ + TIFF_LONG = 4, /* 32-bit unsigned integer */ + TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ + TIFF_SBYTE = 6, /* !8-bit signed integer */ + TIFF_UNDEFINED = 7, /* !8-bit untyped data */ + TIFF_SSHORT = 8, /* !16-bit signed integer */ + TIFF_SLONG = 9, /* !32-bit signed integer */ + TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ + TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ + TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ + TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */ + TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */ + TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */ + TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */ } TIFFDataType; /* * TIFF Tag Definitions. */ -#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ -#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ -#define FILETYPE_PAGE 0x2 /* one page of many */ -#define FILETYPE_MASK 0x4 /* transparency mask */ -#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ -#define OFILETYPE_IMAGE 1 /* full resolution image data */ -#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ -#define OFILETYPE_PAGE 3 /* one page of many */ -#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ -#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ -#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ -#define TIFFTAG_COMPRESSION 259 /* data compression technique */ -#define COMPRESSION_NONE 1 /* dump mode */ -#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ -#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ -#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */ -#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ -#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */ -#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ -#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ -#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ -#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */ -#define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */ -#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ -#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ -#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ -#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ +#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ +#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ +#define FILETYPE_PAGE 0x2 /* one page of many */ +#define FILETYPE_MASK 0x4 /* transparency mask */ +#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ +#define OFILETYPE_IMAGE 1 /* full resolution image data */ +#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ +#define OFILETYPE_PAGE 3 /* one page of many */ +#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ +#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ +#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ +#define TIFFTAG_COMPRESSION 259 /* data compression technique */ +#define COMPRESSION_NONE 1 /* dump mode */ +#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ +#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ +#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */ +#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ +#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */ +#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ +#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ +#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ +#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */ +#define COMPRESSION_T43 \ + 10 /* !TIFF/FX T.43 colour by layered JBIG compression */ +#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ +#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ +#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ +#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ /* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */ -#define COMPRESSION_IT8CTPAD 32895 /* IT8 CT w/padding */ -#define COMPRESSION_IT8LW 32896 /* IT8 Linework RLE */ -#define COMPRESSION_IT8MP 32897 /* IT8 Monochrome picture */ -#define COMPRESSION_IT8BL 32898 /* IT8 Binary line art */ +#define COMPRESSION_IT8CTPAD 32895 /* IT8 CT w/padding */ +#define COMPRESSION_IT8LW 32896 /* IT8 Linework RLE */ +#define COMPRESSION_IT8MP 32897 /* IT8 Monochrome picture */ +#define COMPRESSION_IT8BL 32898 /* IT8 Binary line art */ /* compression codes 32908-32911 are reserved for Pixar */ -#define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */ -#define COMPRESSION_PIXARLOG 32909 /* Pixar companded 11bit ZIP */ -#define COMPRESSION_DEFLATE 32946 /* Deflate compression, legacy tag */ -#define COMPRESSION_ADOBE_DEFLATE 8 /* Deflate compression, - as recognized by Adobe */ +#define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */ +#define COMPRESSION_PIXARLOG 32909 /* Pixar companded 11bit ZIP */ +#define COMPRESSION_DEFLATE 32946 /* Deflate compression, legacy tag */ +#define COMPRESSION_ADOBE_DEFLATE \ + 8 /* Deflate compression, \ + as recognized by Adobe */ /* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */ -#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ -#define COMPRESSION_JBIG 34661 /* ISO JBIG */ -#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ -#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ -#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ -#define COMPRESSION_LERC 34887 /* ESRI Lerc codec: https://github.com/Esri/lerc */ +#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ +#define COMPRESSION_JBIG 34661 /* ISO JBIG */ +#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ +#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ +#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ +#define COMPRESSION_LERC \ + 34887 /* ESRI Lerc codec: https://github.com/Esri/lerc */ /* compression codes 34887-34889 are reserved for ESRI */ -#define COMPRESSION_LZMA 34925 /* LZMA2 */ -#define COMPRESSION_ZSTD 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */ -#define COMPRESSION_WEBP 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */ -#define COMPRESSION_JXL 50002 /* JPEGXL: WARNING not registered in Adobe-maintained registry */ -#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ -#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ -#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ -#define PHOTOMETRIC_RGB 2 /* RGB color model */ -#define PHOTOMETRIC_PALETTE 3 /* color map indexed */ -#define PHOTOMETRIC_MASK 4 /* $holdout mask */ -#define PHOTOMETRIC_SEPARATED 5 /* !color separations */ -#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ -#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ -#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ -#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ -#define PHOTOMETRIC_CFA 32803 /* color filter array */ -#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ -#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ -#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ -#define THRESHHOLD_BILEVEL 1 /* b&w art scan */ -#define THRESHHOLD_HALFTONE 2 /* or dithered scan */ -#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ -#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ -#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ -#define TIFFTAG_FILLORDER 266 /* data order within a byte */ -#define FILLORDER_MSB2LSB 1 /* most significant -> least */ -#define FILLORDER_LSB2MSB 2 /* least significant -> most */ -#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ -#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ -#define TIFFTAG_MAKE 271 /* scanner manufacturer name */ -#define TIFFTAG_MODEL 272 /* scanner model name/number */ -#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ -#define TIFFTAG_ORIENTATION 274 /* +image orientation */ -#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ -#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ -#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ -#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ -#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ -#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ -#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ -#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ -#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ -#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ -#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ -#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ -#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ -#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ -#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ -#define TIFFTAG_PLANARCONFIG 284 /* storage organization */ -#define PLANARCONFIG_CONTIG 1 /* single image plane */ -#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ -#define TIFFTAG_PAGENAME 285 /* page name image is from */ -#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ -#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ -#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ -#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ -#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ -#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ -#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ -#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ -#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ -#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ -#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ -#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ -#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */ -#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ -#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ -#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ -#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ -#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */ -#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ -#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ -#define RESUNIT_NONE 1 /* no meaningful units */ -#define RESUNIT_INCH 2 /* english */ -#define RESUNIT_CENTIMETER 3 /* metric */ -#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ -#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ -#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ -#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ -#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ -#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ -#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ -#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ -#define TIFFTAG_SOFTWARE 305 /* name & release */ -#define TIFFTAG_DATETIME 306 /* creation date and time */ -#define TIFFTAG_ARTIST 315 /* creator of image */ -#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ -#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ -#define PREDICTOR_NONE 1 /* no prediction scheme used */ -#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */ -#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */ -#define TIFFTAG_WHITEPOINT 318 /* image white point */ -#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ -#define TIFFTAG_COLORMAP 320 /* RGB map for palette image */ -#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ -#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */ -#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */ -#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ -#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ -#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ -#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ -#define CLEANFAXDATA_CLEAN 0 /* no errors detected */ -#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ -#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ -#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ -#define TIFFTAG_SUBIFD 330 /* subimage descriptors */ -#define TIFFTAG_INKSET 332 /* !inks in separated image */ -#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */ -#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */ -#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ -#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ -#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ -#define TIFFTAG_TARGETPRINTER 337 /* !separation target */ -#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ -#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ -#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ -#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ -#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ -#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ -#define SAMPLEFORMAT_INT 2 /* !signed integer data */ -#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ -#define SAMPLEFORMAT_VOID 4 /* !untyped data */ -#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */ -#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */ -#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ -#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ -#define TIFFTAG_CLIPPATH 343 /* %ClipPath - [Adobe TIFF technote 2] */ -#define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits - [Adobe TIFF technote 2] */ -#define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits - [Adobe TIFF technote 2] */ -#define TIFFTAG_INDEXED 346 /* %Indexed - [Adobe TIFF Technote 3] */ -#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ -#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */ +#define COMPRESSION_LZMA 34925 /* LZMA2 */ +#define COMPRESSION_ZSTD \ + 50000 /* ZSTD: WARNING not registered in Adobe-maintained registry */ +#define COMPRESSION_WEBP \ + 50001 /* WEBP: WARNING not registered in Adobe-maintained registry */ +#define COMPRESSION_JXL \ + 50002 /* JPEGXL: WARNING not registered in Adobe-maintained registry */ +#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ +#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ +#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ +#define PHOTOMETRIC_RGB 2 /* RGB color model */ +#define PHOTOMETRIC_PALETTE 3 /* color map indexed */ +#define PHOTOMETRIC_MASK 4 /* $holdout mask */ +#define PHOTOMETRIC_SEPARATED 5 /* !color separations */ +#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ +#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ +#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ +#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ +#define PHOTOMETRIC_CFA 32803 /* color filter array */ +#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ +#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ +#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ +#define THRESHHOLD_BILEVEL 1 /* b&w art scan */ +#define THRESHHOLD_HALFTONE 2 /* or dithered scan */ +#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ +#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ +#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ +#define TIFFTAG_FILLORDER 266 /* data order within a byte */ +#define FILLORDER_MSB2LSB 1 /* most significant -> least */ +#define FILLORDER_LSB2MSB 2 /* least significant -> most */ +#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ +#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ +#define TIFFTAG_MAKE 271 /* scanner manufacturer name */ +#define TIFFTAG_MODEL 272 /* scanner model name/number */ +#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ +#define TIFFTAG_ORIENTATION 274 /* +image orientation */ +#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ +#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ +#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ +#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ +#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ +#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ +#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ +#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ +#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ +#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ +#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ +#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ +#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ +#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ +#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ +#define TIFFTAG_PLANARCONFIG 284 /* storage organization */ +#define PLANARCONFIG_CONTIG 1 /* single image plane */ +#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ +#define TIFFTAG_PAGENAME 285 /* page name image is from */ +#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ +#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ +#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ +#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ +#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ +#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ +#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ +#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */ +#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ +#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ +#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ +#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */ +#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ +#define RESUNIT_NONE 1 /* no meaningful units */ +#define RESUNIT_INCH 2 /* english */ +#define RESUNIT_CENTIMETER 3 /* metric */ +#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ +#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ +#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ +#define TIFFTAG_SOFTWARE 305 /* name & release */ +#define TIFFTAG_DATETIME 306 /* creation date and time */ +#define TIFFTAG_ARTIST 315 /* creator of image */ +#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ +#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ +#define PREDICTOR_NONE 1 /* no prediction scheme used */ +#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */ +#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */ +#define TIFFTAG_WHITEPOINT 318 /* image white point */ +#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ +#define TIFFTAG_COLORMAP 320 /* RGB map for palette image */ +#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ +#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */ +#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */ +#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ +#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ +#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ +#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ +#define CLEANFAXDATA_CLEAN 0 /* no errors detected */ +#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ +#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ +#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ +#define TIFFTAG_SUBIFD 330 /* subimage descriptors */ +#define TIFFTAG_INKSET 332 /* !inks in separated image */ +#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */ +#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */ +#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ +#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ +#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ +#define TIFFTAG_TARGETPRINTER 337 /* !separation target */ +#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ +#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ +#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ +#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ +#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ +#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ +#define SAMPLEFORMAT_INT 2 /* !signed integer data */ +#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ +#define SAMPLEFORMAT_VOID 4 /* !untyped data */ +#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */ +#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */ +#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ +#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ +#define TIFFTAG_CLIPPATH \ + 343 /* %ClipPath \ + [Adobe TIFF technote 2] */ +#define TIFFTAG_XCLIPPATHUNITS \ + 344 /* %XClipPathUnits \ + [Adobe TIFF technote 2] */ +#define TIFFTAG_YCLIPPATHUNITS \ + 345 /* %YClipPathUnits \ + [Adobe TIFF technote 2] */ +#define TIFFTAG_INDEXED \ + 346 /* %Indexed \ + [Adobe TIFF Technote 3] */ +#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ +#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */ /* Tags 400-435 are from the TIFF/FX spec */ -#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */ -#define TIFFTAG_PROFILETYPE 401 /* ! */ -#define PROFILETYPE_UNSPECIFIED 0 /* ! */ -#define PROFILETYPE_G3_FAX 1 /* ! */ -#define TIFFTAG_FAXPROFILE 402 /* ! */ -#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */ -#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */ -#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */ -#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */ -#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */ -#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */ -#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */ -#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */ -#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */ -#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */ -#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */ -#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */ -#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */ -#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */ -#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */ -#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */ -#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */ -#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */ +#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */ +#define TIFFTAG_PROFILETYPE 401 /* ! */ +#define PROFILETYPE_UNSPECIFIED 0 /* ! */ +#define PROFILETYPE_G3_FAX 1 /* ! */ +#define TIFFTAG_FAXPROFILE 402 /* ! */ +#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */ +#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */ +#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */ +#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */ +#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */ +#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */ +#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */ +#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */ +#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */ +#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */ +#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */ +#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */ +#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */ +#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */ +#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */ +#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */ +#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */ +#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */ /* * Tags 512-521 are obsoleted by Technical Note #2 which specifies a * revised JPEG-in-TIFF scheme. */ -#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ -#define JPEGPROC_BASELINE 1 /* !baseline sequential */ -#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ -#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ -#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ -#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ -#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ -#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ -#define TIFFTAG_JPEGQTABLES 519 /* !Q matrix offsets */ -#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ -#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ -#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ -#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ -#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ -#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ -#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ -#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ -#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */ -#define TIFFTAG_XMLPACKET 700 /* %XML packet - [Adobe XMP Specification, - January 2004 */ -#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID - [Adobe TIFF technote] */ -#define TIFFTAG_TIFFANNOTATIONDATA 32932 /* http://web.archive.org/web/20050309141348/http://www.kofile.com/support%20pro/faqs/annospec.htm */ +#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ +#define JPEGPROC_BASELINE 1 /* !baseline sequential */ +#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ +#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ +#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ +#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ +#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ +#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ +#define TIFFTAG_JPEGQTABLES 519 /* !Q matrix offsets */ +#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ +#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ +#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ +#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ +#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ +#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ +#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ +#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ +#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */ +#define TIFFTAG_XMLPACKET \ + 700 /* %XML packet \ + [Adobe XMP Specification, \ + January 2004 */ +#define TIFFTAG_OPIIMAGEID \ + 32781 /* %OPI ImageID \ + [Adobe TIFF technote] */ +#define TIFFTAG_TIFFANNOTATIONDATA \ + 32932 /* http://web.archive.org/web/20050309141348/http://www.kofile.com/support%20pro/faqs/annospec.htm \ + */ /* tags 32952-32956 are private tags registered to Island Graphics */ -#define TIFFTAG_REFPTS 32953 /* image reference points */ -#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ -#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ -#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ +#define TIFFTAG_REFPTS 32953 /* image reference points */ +#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ +#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ +#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ /* tags 32995-32999 are private tags registered to SGI */ -#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ -#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ -#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ -#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ +#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ +#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ +#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ +#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ /* tags 33300-33309 are private tags registered to Pixar */ /* * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH - * are set when an image has been cropped out of a larger image. + * are set when an image has been cropped out of a larger image. * They reflect the size of the original uncropped image. * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used * to determine the position of the smaller image in the larger one. */ -#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ -#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ - /* Tags 33302-33306 are used to identify special image modes and data - * used by Pixar's texture formats. - */ -#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */ -#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */ -#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */ +#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ +#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ +/* Tags 33302-33306 are used to identify special image modes and data + * used by Pixar's texture formats. + */ +#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */ +#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */ +#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */ #define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305 #define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306 /* tag 33405 is a private tag registered to Eastman Kodak */ -#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ -#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */ -#define TIFFTAG_CFAPATTERN 33422 /* color filter array pattern */ +#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ +#define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */ +#define TIFFTAG_CFAPATTERN 33422 /* color filter array pattern */ /* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ -#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ +#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ /* Tags 33445-33452 are used for GEL fileformat, see * http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_FILETAG 33445 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_SCALEPIXEL 33446 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_COLORTABLE 33447 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_LABNAME 33448 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_SAMPLEINFO 33449 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_PREPDATE 33450 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_PREPTIME 33451 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ -#define TIFFTAG_MD_FILEUNITS 33452 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ +#define TIFFTAG_MD_FILETAG \ + 33445 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf \ + */ +#define TIFFTAG_MD_SCALEPIXEL \ + 33446 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf \ + */ +#define TIFFTAG_MD_COLORTABLE \ + 33447 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf \ + */ +#define TIFFTAG_MD_LABNAME \ + 33448 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf \ + */ +#define TIFFTAG_MD_SAMPLEINFO \ + 33449 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf \ + */ +#define TIFFTAG_MD_PREPDATE \ + 33450 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf \ + */ +#define TIFFTAG_MD_PREPTIME \ + 33451 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf \ + */ +#define TIFFTAG_MD_FILEUNITS \ + 33452 /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf \ + */ /* IPTC TAG from RichTIFF specifications */ -#define TIFFTAG_RICHTIFFIPTC 33723 -#define TIFFTAG_INGR_PACKET_DATA_TAG 33918 /* Intergraph Application specific storage. */ -#define TIFFTAG_INGR_FLAG_REGISTERS 33919 /* Intergraph Application specific flags. */ -#define TIFFTAG_IRASB_TRANSORMATION_MATRIX 33920 /* Originally part of Intergraph's GeoTIFF tags, but likely understood by IrasB only. */ -#define TIFFTAG_MODELTIEPOINTTAG 33922 /* GeoTIFF */ +#define TIFFTAG_RICHTIFFIPTC 33723 +#define TIFFTAG_INGR_PACKET_DATA_TAG \ + 33918 /* Intergraph Application specific storage. */ +#define TIFFTAG_INGR_FLAG_REGISTERS \ + 33919 /* Intergraph Application specific flags. */ +#define TIFFTAG_IRASB_TRANSORMATION_MATRIX \ + 33920 /* Originally part of Intergraph's GeoTIFF tags, but likely \ + understood by IrasB only. */ +#define TIFFTAG_MODELTIEPOINTTAG 33922 /* GeoTIFF */ /* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */ -#define TIFFTAG_IT8SITE 34016 /* site name */ -#define TIFFTAG_IT8COLORSEQUENCE 34017 /* color seq. [RGB,CMYK,etc] */ -#define TIFFTAG_IT8HEADER 34018 /* DDES Header */ -#define TIFFTAG_IT8RASTERPADDING 34019 /* raster scanline padding */ -#define TIFFTAG_IT8BITSPERRUNLENGTH 34020 /* # of bits in short run */ -#define TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH 34021/* # of bits in long run */ -#define TIFFTAG_IT8COLORTABLE 34022 /* LW colortable */ -#define TIFFTAG_IT8IMAGECOLORINDICATOR 34023 /* BP/BL image color switch */ -#define TIFFTAG_IT8BKGCOLORINDICATOR 34024 /* BP/BL bg color switch */ -#define TIFFTAG_IT8IMAGECOLORVALUE 34025 /* BP/BL image color value */ -#define TIFFTAG_IT8BKGCOLORVALUE 34026 /* BP/BL bg color value */ -#define TIFFTAG_IT8PIXELINTENSITYRANGE 34027 /* MP pixel intensity value */ -#define TIFFTAG_IT8TRANSPARENCYINDICATOR 34028 /* HC transparency switch */ -#define TIFFTAG_IT8COLORCHARACTERIZATION 34029 /* color character. table */ -#define TIFFTAG_IT8HCUSAGE 34030 /* HC usage indicator */ -#define TIFFTAG_IT8TRAPINDICATOR 34031 /* Trapping indicator - (untrapped=0, trapped=1) */ -#define TIFFTAG_IT8CMYKEQUIVALENT 34032 /* CMYK color equivalents */ +#define TIFFTAG_IT8SITE 34016 /* site name */ +#define TIFFTAG_IT8COLORSEQUENCE 34017 /* color seq. [RGB,CMYK,etc] */ +#define TIFFTAG_IT8HEADER 34018 /* DDES Header */ +#define TIFFTAG_IT8RASTERPADDING 34019 /* raster scanline padding */ +#define TIFFTAG_IT8BITSPERRUNLENGTH 34020 /* # of bits in short run */ +#define TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH 34021 /* # of bits in long run */ +#define TIFFTAG_IT8COLORTABLE 34022 /* LW colortable */ +#define TIFFTAG_IT8IMAGECOLORINDICATOR 34023 /* BP/BL image color switch */ +#define TIFFTAG_IT8BKGCOLORINDICATOR 34024 /* BP/BL bg color switch */ +#define TIFFTAG_IT8IMAGECOLORVALUE 34025 /* BP/BL image color value */ +#define TIFFTAG_IT8BKGCOLORVALUE 34026 /* BP/BL bg color value */ +#define TIFFTAG_IT8PIXELINTENSITYRANGE 34027 /* MP pixel intensity value */ +#define TIFFTAG_IT8TRANSPARENCYINDICATOR 34028 /* HC transparency switch */ +#define TIFFTAG_IT8COLORCHARACTERIZATION 34029 /* color character. table */ +#define TIFFTAG_IT8HCUSAGE 34030 /* HC usage indicator */ +#define TIFFTAG_IT8TRAPINDICATOR \ + 34031 /* Trapping indicator \ + (untrapped=0, trapped=1) */ +#define TIFFTAG_IT8CMYKEQUIVALENT 34032 /* CMYK color equivalents */ /* tags 34232-34236 are private tags registered to Texas Instruments */ -#define TIFFTAG_FRAMECOUNT 34232 /* Sequence Frame Count */ -#define TIFFTAG_MODELTRANSFORMATIONTAG 34264 /* Used in interchangeable GeoTIFF files */ +#define TIFFTAG_FRAMECOUNT 34232 /* Sequence Frame Count */ +#define TIFFTAG_MODELTRANSFORMATIONTAG \ + 34264 /* Used in interchangeable GeoTIFF files */ /* tag 34377 is private tag registered to Adobe for PhotoShop */ -#define TIFFTAG_PHOTOSHOP 34377 +#define TIFFTAG_PHOTOSHOP 34377 /* tags 34665, 34853 and 40965 are documented in EXIF specification */ -#define TIFFTAG_EXIFIFD 34665 /* Pointer to EXIF private directory */ +#define TIFFTAG_EXIFIFD 34665 /* Pointer to EXIF private directory */ /* tag 34750 is a private tag registered to Adobe? */ -#define TIFFTAG_ICCPROFILE 34675 /* ICC profile data */ -#define TIFFTAG_IMAGELAYER 34732 /* !TIFF/FX image layer information */ +#define TIFFTAG_ICCPROFILE 34675 /* ICC profile data */ +#define TIFFTAG_IMAGELAYER 34732 /* !TIFF/FX image layer information */ /* tag 34750 is a private tag registered to Pixel Magic */ -#define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */ -#define TIFFTAG_GPSIFD 34853 /* Pointer to GPS private directory */ +#define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */ +#define TIFFTAG_GPSIFD 34853 /* Pointer to GPS private directory */ /* tags 34908-34914 are private tags registered to SGI */ -#define TIFFTAG_FAXRECVPARAMS 34908 /* encoded Class 2 ses. params */ -#define TIFFTAG_FAXSUBADDRESS 34909 /* received SubAddr string */ -#define TIFFTAG_FAXRECVTIME 34910 /* receive time (secs) */ -#define TIFFTAG_FAXDCS 34911 /* encoded fax ses. params, Table 2/T.30 */ +#define TIFFTAG_FAXRECVPARAMS 34908 /* encoded Class 2 ses. params */ +#define TIFFTAG_FAXSUBADDRESS 34909 /* received SubAddr string */ +#define TIFFTAG_FAXRECVTIME 34910 /* receive time (secs) */ +#define TIFFTAG_FAXDCS 34911 /* encoded fax ses. params, Table 2/T.30 */ /* tags 37439-37443 are registered to SGI <gregl@sgi.com> */ -#define TIFFTAG_STONITS 37439 /* Sample value to Nits */ +#define TIFFTAG_STONITS 37439 /* Sample value to Nits */ /* tag 34929 is a private tag registered to FedEx */ -#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ -#define TIFFTAG_IMAGESOURCEDATA 37724 /* http://justsolve.archiveteam.org/wiki/PSD, http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/ */ -#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */ -#define TIFFTAG_GDAL_METADATA 42112 /* Used by the GDAL library */ -#define TIFFTAG_GDAL_NODATA 42113 /* Used by the GDAL library */ -#define TIFFTAG_OCE_SCANJOB_DESCRIPTION 50215 /* Used in the Oce scanning process */ -#define TIFFTAG_OCE_APPLICATION_SELECTOR 50216 /* Used in the Oce scanning process. */ -#define TIFFTAG_OCE_IDENTIFICATION_NUMBER 50217 -#define TIFFTAG_OCE_IMAGELOGIC_CHARACTERISTICS 50218 +#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ +#define TIFFTAG_IMAGESOURCEDATA \ + 37724 /* http://justsolve.archiveteam.org/wiki/PSD, \ + http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/ */ +#define TIFFTAG_INTEROPERABILITYIFD \ + 40965 /* Pointer to Interoperability private directory */ +#define TIFFTAG_GDAL_METADATA 42112 /* Used by the GDAL library */ +#define TIFFTAG_GDAL_NODATA 42113 /* Used by the GDAL library */ +#define TIFFTAG_OCE_SCANJOB_DESCRIPTION \ + 50215 /* Used in the Oce scanning process */ +#define TIFFTAG_OCE_APPLICATION_SELECTOR \ + 50216 /* Used in the Oce scanning process. */ +#define TIFFTAG_OCE_IDENTIFICATION_NUMBER 50217 +#define TIFFTAG_OCE_IMAGELOGIC_CHARACTERISTICS 50218 /* tags 50674 to 50677 are reserved for ESRI */ -#define TIFFTAG_LERC_PARAMETERS 50674 /* Stores LERC version and additional compression method */ +#define TIFFTAG_LERC_PARAMETERS \ + 50674 /* Stores LERC version and additional compression method */ /* Adobe Digital Negative (DNG) format tags */ -#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */ -#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */ -#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */ -#define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model - name */ -#define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space - mapping */ -#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */ -#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */ -#define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for - the BlackLevel tag */ -#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */ -#define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level - differences (columns) */ -#define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level - differences (rows) */ -#define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding - level */ -#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */ -#define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image - area */ -#define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image - area */ -#define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space - transformation matrix 1 */ -#define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space - transformation matrix 2 */ -#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */ -#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */ -#define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction - matrix 1 */ -#define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction - matrix 2 */ -#define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw - values*/ -#define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in - linear reference space */ -#define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in - x-y chromaticity - coordinates */ -#define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero - point */ -#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */ -#define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of - sharpening */ -#define TIFFTAG_BAYERGREENSPLIT 50733 /* &how closely the values of - the green pixels in the - blue/green rows track the - values of the green pixels - in the red/green rows */ -#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */ -#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */ -#define TIFFTAG_LENSINFO 50736 /* info about the lens */ -#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */ -#define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the - camera's anti-alias filter */ -#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */ -#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */ -#define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote - tag is safe to preserve - along with the rest of the - EXIF data */ -#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */ -#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */ -#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */ -#define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for - the raw image data */ -#define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original - raw file */ -#define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original - raw file */ -#define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels - of the sensor */ -#define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates - of fully masked pixels */ -#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */ -#define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space - into ICC profile space */ -#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */ -#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */ +#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */ +#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */ +#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */ +#define TIFFTAG_LOCALIZEDCAMERAMODEL \ + 50709 /* &localized camera model \ + name */ +#define TIFFTAG_CFAPLANECOLOR \ + 50710 /* &CFAPattern->LinearRaw space \ + mapping */ +#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */ +#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */ +#define TIFFTAG_BLACKLEVELREPEATDIM \ + 50713 /* &repeat pattern size for \ + the BlackLevel tag */ +#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */ +#define TIFFTAG_BLACKLEVELDELTAH \ + 50715 /* &zero light encoding level \ + differences (columns) */ +#define TIFFTAG_BLACKLEVELDELTAV \ + 50716 /* &zero light encoding level \ + differences (rows) */ +#define TIFFTAG_WHITELEVEL \ + 50717 /* &fully saturated encoding \ + level */ +#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */ +#define TIFFTAG_DEFAULTCROPORIGIN \ + 50719 /* &origin of the final image \ + area */ +#define TIFFTAG_DEFAULTCROPSIZE \ + 50720 /* &size of the final image \ + area */ +#define TIFFTAG_COLORMATRIX1 \ + 50721 /* &XYZ->reference color space \ + transformation matrix 1 */ +#define TIFFTAG_COLORMATRIX2 \ + 50722 /* &XYZ->reference color space \ + transformation matrix 2 */ +#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */ +#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */ +#define TIFFTAG_REDUCTIONMATRIX1 \ + 50725 /* &dimensionality reduction \ + matrix 1 */ +#define TIFFTAG_REDUCTIONMATRIX2 \ + 50726 /* &dimensionality reduction \ + matrix 2 */ +#define TIFFTAG_ANALOGBALANCE \ + 50727 /* &gain applied the stored raw \ + values*/ +#define TIFFTAG_ASSHOTNEUTRAL \ + 50728 /* &selected white balance in \ + linear reference space */ +#define TIFFTAG_ASSHOTWHITEXY \ + 50729 /* &selected white balance in \ + x-y chromaticity \ + coordinates */ +#define TIFFTAG_BASELINEEXPOSURE \ + 50730 /* &how much to move the zero \ + point */ +#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */ +#define TIFFTAG_BASELINESHARPNESS \ + 50732 /* &relative amount of \ + sharpening */ +#define TIFFTAG_BAYERGREENSPLIT \ + 50733 /* &how closely the values of \ + the green pixels in the \ + blue/green rows track the \ + values of the green pixels \ + in the red/green rows */ +#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */ +#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */ +#define TIFFTAG_LENSINFO 50736 /* info about the lens */ +#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */ +#define TIFFTAG_ANTIALIASSTRENGTH \ + 50738 /* &relative strength of the \ + camera's anti-alias filter */ +#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */ +#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */ +#define TIFFTAG_MAKERNOTESAFETY \ + 50741 /* &whether the EXIF MakerNote \ + tag is safe to preserve \ + along with the rest of the \ + EXIF data */ +#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */ +#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */ +#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */ +#define TIFFTAG_RAWDATAUNIQUEID \ + 50781 /* &unique identifier for \ + the raw image data */ +#define TIFFTAG_ORIGINALRAWFILENAME \ + 50827 /* &file name of the original \ + raw file */ +#define TIFFTAG_ORIGINALRAWFILEDATA \ + 50828 /* &contents of the original \ + raw file */ +#define TIFFTAG_ACTIVEAREA \ + 50829 /* &active (non-masked) pixels \ + of the sensor */ +#define TIFFTAG_MASKEDAREAS \ + 50830 /* &list of coordinates \ + of fully masked pixels */ +#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */ +#define TIFFTAG_ASSHOTPREPROFILEMATRIX \ + 50832 /* map cameras's color space \ + into ICC profile space */ +#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */ +#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */ -#define TIFFTAG_RPCCOEFFICIENT 50844 /* Define by GDAL for geospatial georeferencing through RPC: http://geotiff.maptools.org/rpc_prop.html */ +#define TIFFTAG_RPCCOEFFICIENT \ + 50844 /* Define by GDAL for geospatial georeferencing through RPC: \ + http://geotiff.maptools.org/rpc_prop.html */ -#define TIFFTAG_ALIAS_LAYER_METADATA 50784 /* Alias Sketchbook Pro layer usage description. */ +#define TIFFTAG_ALIAS_LAYER_METADATA \ + 50784 /* Alias Sketchbook Pro layer usage description. */ /* GeoTIFF DGIWG */ -#define TIFFTAG_TIFF_RSID 50908 /* https://www.awaresystems.be/imaging/tiff/tifftags/tiff_rsid.html */ -#define TIFFTAG_GEO_METADATA 50909 /* https://www.awaresystems.be/imaging/tiff/tifftags/geo_metadata.html */ +#define TIFFTAG_TIFF_RSID \ + 50908 /* https://www.awaresystems.be/imaging/tiff/tifftags/tiff_rsid.html \ + */ +#define TIFFTAG_GEO_METADATA \ + 50909 /* https://www.awaresystems.be/imaging/tiff/tifftags/geo_metadata.html \ + */ -#define TIFFTAG_EXTRACAMERAPROFILES 50933 /* http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf */ +#define TIFFTAG_EXTRACAMERAPROFILES \ + 50933 /* http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf \ + */ /* tag 65535 is an undefined tag used by Eastman Kodak */ -#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ +#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ /* * The following are ``pseudo tags'' that can be used to control @@ -604,202 +686,285 @@ typedef enum { * http://www.remotesensing.org/libtiff/bugs.html with the appropriate * C definitions to add. */ -#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ -#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ -#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ -#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ -#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ -#define FAXMODE_WORDALIGN 0x0008 /* word align row */ -#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ -#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ +#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ +#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ +#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ +#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ +#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ +#define FAXMODE_WORDALIGN 0x0008 /* word align row */ +#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ +#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ /* Note: quality level is on the IJG 0-100 scale. Default value is 75 */ -#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ -#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ -#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ -#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ -#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ -#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ +#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ +#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ +#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ +#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ +#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ +#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ /* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */ -#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ -#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ -#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ -#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ -#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ -#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ -#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ -#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ +#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ +#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ +#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ +#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ +#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ +#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ +#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ +#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ /* 65550-65556 are allocated to Oceana Matrix <dev@oceana.com> */ -#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ -#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ -#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ -#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ -#define DCSIMAGERFILTER_IR 0 /* infrared filter */ -#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ -#define DCSIMAGERFILTER_CFA 2 /* color filter array */ -#define DCSIMAGERFILTER_OTHER 3 /* other filter */ -#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ -#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ -#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ -#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ -#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ -#define TIFFTAG_DCSGAMMA 65554 /* gamma value */ -#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ -#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ +#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ +#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ +#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ +#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ +#define DCSIMAGERFILTER_IR 0 /* infrared filter */ +#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ +#define DCSIMAGERFILTER_CFA 2 /* color filter array */ +#define DCSIMAGERFILTER_OTHER 3 /* other filter */ +#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ +#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ +#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ +#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ +#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ +#define TIFFTAG_DCSGAMMA 65554 /* gamma value */ +#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ +#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ /* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */ -#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ -#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ +#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ +#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ /* 65559 is allocated to Oceana Matrix <dev@oceana.com> */ -#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ -#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ -#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ -#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ -#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ -#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ -#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/ -#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/ -#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */ -#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */ -#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */ -#define PERSAMPLE_MERGED 0 /* present as a single value */ -#define PERSAMPLE_MULTI 1 /* present as multiple values */ -#define TIFFTAG_ZSTD_LEVEL 65564 /* ZSTD compression level */ -#define TIFFTAG_LERC_VERSION 65565 /* LERC version */ -#define LERC_VERSION_2_4 4 -#define TIFFTAG_LERC_ADD_COMPRESSION 65566 /* LERC additional compression */ -#define LERC_ADD_COMPRESSION_NONE 0 -#define LERC_ADD_COMPRESSION_DEFLATE 1 -#define LERC_ADD_COMPRESSION_ZSTD 2 -#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */ -#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level */ -#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy */ -#define TIFFTAG_DEFLATE_SUBCODEC 65570 /* ZIP codec: to get/set the sub-codec to use. Will default to libdeflate when available */ -#define DEFLATE_SUBCODEC_ZLIB 0 -#define DEFLATE_SUBCODEC_LIBDEFLATE 1 +#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ +#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ +#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ +#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ +#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ +#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ +#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/ +#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/ +#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */ +#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */ +#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */ +#define PERSAMPLE_MERGED 0 /* present as a single value */ +#define PERSAMPLE_MULTI 1 /* present as multiple values */ +#define TIFFTAG_ZSTD_LEVEL 65564 /* ZSTD compression level */ +#define TIFFTAG_LERC_VERSION 65565 /* LERC version */ +#define LERC_VERSION_2_4 4 +#define TIFFTAG_LERC_ADD_COMPRESSION 65566 /* LERC additional compression */ +#define LERC_ADD_COMPRESSION_NONE 0 +#define LERC_ADD_COMPRESSION_DEFLATE 1 +#define LERC_ADD_COMPRESSION_ZSTD 2 +#define TIFFTAG_LERC_MAXZERROR 65567 /* LERC maximum error */ +#define TIFFTAG_WEBP_LEVEL 65568 /* WebP compression level */ +#define TIFFTAG_WEBP_LOSSLESS 65569 /* WebP lossless/lossy */ +#define TIFFTAG_DEFLATE_SUBCODEC \ + 65570 /* ZIP codec: to get/set the sub-codec to use. Will default to \ + libdeflate when available */ +#define DEFLATE_SUBCODEC_ZLIB 0 +#define DEFLATE_SUBCODEC_LIBDEFLATE 1 /* * EXIF tags */ -#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */ -#define EXIFTAG_FNUMBER 33437 /* F number */ -#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */ -#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ -#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */ -#define EXIFTAG_PHOTOGRAPHICSENSITIVITY 34855 /* Photographic Sensitivity (new name for tag 34855) */ -#define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */ -#define EXIFTAG_EXIFVERSION 36864 /* Exif version */ -#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original - data generation */ -#define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital - data generation */ -#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */ -#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ -#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ -#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */ -#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */ -#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */ -#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ -#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */ -#define EXIFTAG_METERINGMODE 37383 /* Metering mode */ -#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */ -#define EXIFTAG_FLASH 37385 /* Flash */ -#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */ -#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */ -#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */ -#define EXIFTAG_USERCOMMENT 37510 /* User comments */ -#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */ -#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */ -#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */ -#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */ -#define EXIFTAG_COLORSPACE 40961 /* Color space information */ -#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */ -#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */ -#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */ -#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */ -#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */ -#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */ -#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */ -#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */ -#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */ -#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */ -#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */ -#define EXIFTAG_FILESOURCE 41728 /* File source */ -#define EXIFTAG_SCENETYPE 41729 /* Scene type */ -#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */ -#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */ -#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */ -#define EXIFTAG_WHITEBALANCE 41987 /* White balance */ -#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */ -#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */ -#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */ -#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ -#define EXIFTAG_CONTRAST 41992 /* Contrast */ -#define EXIFTAG_SATURATION 41993 /* Saturation */ -#define EXIFTAG_SHARPNESS 41994 /* Sharpness */ -#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */ -#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */ -#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */ +#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */ +#define EXIFTAG_FNUMBER 33437 /* F number */ +#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */ +#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ +#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */ +#define EXIFTAG_PHOTOGRAPHICSENSITIVITY \ + 34855 /* Photographic Sensitivity (new name for tag 34855) */ +#define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */ +#define EXIFTAG_EXIFVERSION 36864 /* Exif version */ +#define EXIFTAG_DATETIMEORIGINAL \ + 36867 /* Date and time of original \ + data generation */ +#define EXIFTAG_DATETIMEDIGITIZED \ + 36868 /* Date and time of digital \ + data generation */ +#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */ +#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ +#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ +#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */ +#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */ +#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */ +#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ +#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */ +#define EXIFTAG_METERINGMODE 37383 /* Metering mode */ +#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */ +#define EXIFTAG_FLASH 37385 /* Flash */ +#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */ +#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */ +#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */ +#define EXIFTAG_USERCOMMENT 37510 /* User comments */ +#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */ +#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */ +#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */ +#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */ +#define EXIFTAG_COLORSPACE 40961 /* Color space information */ +#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */ +#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */ +#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */ +#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */ +#define EXIFTAG_SPATIALFREQUENCYRESPONSE \ + 41484 /* Spatial frequency response \ + */ +#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */ +#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */ +#define EXIFTAG_FOCALPLANERESOLUTIONUNIT \ + 41488 /* Focal plane resolution unit \ + */ +#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */ +#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */ +#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */ +#define EXIFTAG_FILESOURCE 41728 /* File source */ +#define EXIFTAG_SCENETYPE 41729 /* Scene type */ +#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */ +#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */ +#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */ +#define EXIFTAG_WHITEBALANCE 41987 /* White balance */ +#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */ +#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */ +#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */ +#define EXIFTAG_GAINCONTROL 41991 /* Gain control */ +#define EXIFTAG_CONTRAST 41992 /* Contrast */ +#define EXIFTAG_SATURATION 41993 /* Saturation */ +#define EXIFTAG_SHARPNESS 41994 /* Sharpness */ +#define EXIFTAG_DEVICESETTINGDESCRIPTION \ + 41995 /* Device settings description \ + */ +#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */ +#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */ /*--: New for EXIF-Version 2.32, May 2019 ... */ -#define EXIFTAG_SENSITIVITYTYPE 34864 /* The SensitivityType tag indicates which one of the parameters of ISO12232 is the PhotographicSensitivity tag. */ -#define EXIFTAG_STANDARDOUTPUTSENSITIVITY 34865 /* This tag indicates the standard output sensitivity value of a camera or input device defined in ISO 12232. */ -#define EXIFTAG_RECOMMENDEDEXPOSUREINDEX 34866 /* recommended exposure index */ -#define EXIFTAG_ISOSPEED 34867 /* ISO speed value */ -#define EXIFTAG_ISOSPEEDLATITUDEYYY 34868 /* ISO speed latitude yyy */ -#define EXIFTAG_ISOSPEEDLATITUDEZZZ 34869 /* ISO speed latitude zzz */ -#define EXIFTAG_OFFSETTIME 36880 /* offset from UTC of the time of DateTime tag. */ -#define EXIFTAG_OFFSETTIMEORIGINAL 36881 /* offset from UTC of the time of DateTimeOriginal tag. */ -#define EXIFTAG_OFFSETTIMEDIGITIZED 36882 /* offset from UTC of the time of DateTimeDigitized tag. */ -#define EXIFTAG_TEMPERATURE 37888 /* Temperature as the ambient situation at the shot in dergee Celsius */ -#define EXIFTAG_HUMIDITY 37889 /* Humidity as the ambient situation at the shot in percent */ -#define EXIFTAG_PRESSURE 37890 /* Pressure as the ambient situation at the shot hecto-Pascal (hPa) */ -#define EXIFTAG_WATERDEPTH 37891 /* WaterDepth as the ambient situation at the shot in meter (m) */ -#define EXIFTAG_ACCELERATION 37892 /* Acceleration (a scalar regardless of direction) as the ambient situation at the shot in units of mGal (10-5 m/s^2) */ -#define EXIFTAG_CAMERAELEVATIONANGLE 37893 /* Elevation/depression. angle of the orientation of the camera(imaging optical axis) as the ambient situation at the shot in degree from -180deg to +180deg. */ -#define EXIFTAG_CAMERAOWNERNAME 42032 /* owner of a camera */ -#define EXIFTAG_BODYSERIALNUMBER 42033 /* serial number of the body of the camera */ -#define EXIFTAG_LENSSPECIFICATION 42034 /* minimum focal length (in mm), maximum focal length (in mm), minimum F number in the minimum focal length, and minimum F number in the maximum focal length, */ -#define EXIFTAG_LENSMAKE 42035 /* the lens manufacturer */ -#define EXIFTAG_LENSMODEL 42036 /* the lens model name and model number */ -#define EXIFTAG_LENSSERIALNUMBER 42037 /* the serial number of the interchangeable lens */ -#define EXIFTAG_GAMMA 42240 /* value of coefficient gamma */ -#define EXIFTAG_COMPOSITEIMAGE 42080 /* composite image */ -#define EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE 42081 /* source image number of composite image */ -#define EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE 42082 /* source exposure times of composite image */ +#define EXIFTAG_SENSITIVITYTYPE \ + 34864 /* The SensitivityType tag indicates which one of the parameters of \ + ISO12232 is the PhotographicSensitivity tag. */ +#define EXIFTAG_STANDARDOUTPUTSENSITIVITY \ + 34865 /* This tag indicates the standard output sensitivity value of a \ + camera or input device defined in ISO 12232. */ +#define EXIFTAG_RECOMMENDEDEXPOSUREINDEX \ + 34866 /* recommended exposure index \ + */ +#define EXIFTAG_ISOSPEED 34867 /* ISO speed value */ +#define EXIFTAG_ISOSPEEDLATITUDEYYY 34868 /* ISO speed latitude yyy */ +#define EXIFTAG_ISOSPEEDLATITUDEZZZ 34869 /* ISO speed latitude zzz */ +#define EXIFTAG_OFFSETTIME \ + 36880 /* offset from UTC of the time of DateTime tag. */ +#define EXIFTAG_OFFSETTIMEORIGINAL \ + 36881 /* offset from UTC of the time of DateTimeOriginal tag. */ +#define EXIFTAG_OFFSETTIMEDIGITIZED \ + 36882 /* offset from UTC of the time of DateTimeDigitized tag. */ +#define EXIFTAG_TEMPERATURE \ + 37888 /* Temperature as the ambient situation at the shot in dergee \ + Celsius */ +#define EXIFTAG_HUMIDITY \ + 37889 /* Humidity as the ambient situation at the shot in percent */ +#define EXIFTAG_PRESSURE \ + 37890 /* Pressure as the ambient situation at the shot hecto-Pascal (hPa) \ + */ +#define EXIFTAG_WATERDEPTH \ + 37891 /* WaterDepth as the ambient situation at the shot in meter (m) */ +#define EXIFTAG_ACCELERATION \ + 37892 /* Acceleration (a scalar regardless of direction) as the ambient \ + situation at the shot in units of mGal (10-5 m/s^2) */ +#define EXIFTAG_CAMERAELEVATIONANGLE \ + 37893 /* Elevation/depression. angle of the orientation of the \ + camera(imaging optical axis) as the ambient situation at the shot \ + in degree from -180deg to +180deg. */ +#define EXIFTAG_CAMERAOWNERNAME 42032 /* owner of a camera */ +#define EXIFTAG_BODYSERIALNUMBER \ + 42033 /* serial number of the body of the camera */ +#define EXIFTAG_LENSSPECIFICATION \ + 42034 /* minimum focal length (in mm), maximum focal length (in mm), \ + minimum F number in the minimum focal length, and minimum F \ + number in the maximum focal length, */ +#define EXIFTAG_LENSMAKE 42035 /* the lens manufacturer */ +#define EXIFTAG_LENSMODEL 42036 /* the lens model name and model number */ +#define EXIFTAG_LENSSERIALNUMBER \ + 42037 /* the serial number of the interchangeable lens */ +#define EXIFTAG_GAMMA 42240 /* value of coefficient gamma */ +#define EXIFTAG_COMPOSITEIMAGE 42080 /* composite image */ +#define EXIFTAG_SOURCEIMAGENUMBEROFCOMPOSITEIMAGE \ + 42081 /* source image number of composite image */ +#define EXIFTAG_SOURCEEXPOSURETIMESOFCOMPOSITEIMAGE \ + 42082 /* source exposure times of composite image */ /* * EXIF-GPS tags (Version 2.31, July 2016) */ -#define GPSTAG_VERSIONID 0 /* Indicates the version of GPSInfoIFD. */ -#define GPSTAG_LATITUDEREF 1 /* Indicates whether the latitude is north or south latitude. */ -#define GPSTAG_LATITUDE 2 /* Indicates the latitude. */ -#define GPSTAG_LONGITUDEREF 3 /* Indicates whether the longitude is east or west longitude. */ -#define GPSTAG_LONGITUDE 4 /* Indicates the longitude. */ -#define GPSTAG_ALTITUDEREF 5 /* Indicates the altitude used as the reference altitude. */ -#define GPSTAG_ALTITUDE 6 /* Indicates the altitude based on the reference in GPSAltitudeRef. */ -#define GPSTAG_TIMESTAMP 7 /* Indicates the time as UTC (Coordinated Universal Time). */ -#define GPSTAG_SATELLITES 8 /* Indicates the GPS satellites used for measurements. */ -#define GPSTAG_STATUS 9 /* Indicates the status of the GPS receiver when the image is recorded. */ -#define GPSTAG_MEASUREMODE 10 /* Indicates the GPS measurement mode. */ -#define GPSTAG_DOP 11 /* Indicates the GPS DOP (data degree of precision). */ -#define GPSTAG_SPEEDREF 12 /* Indicates the unit used to express the GPS receiver speed of movement. */ -#define GPSTAG_SPEED 13 /* Indicates the speed of GPS receiver movement. */ -#define GPSTAG_TRACKREF 14 /* Indicates the reference for giving the direction of GPS receiver movement. */ -#define GPSTAG_TRACK 15 /* Indicates the direction of GPS receiver movement. */ -#define GPSTAG_IMGDIRECTIONREF 16 /* Indicates the reference for giving the direction of the image when it is captured. */ -#define GPSTAG_IMGDIRECTION 17 /* Indicates the direction of the image when it was captured. */ -#define GPSTAG_MAPDATUM 18 /* Indicates the geodetic survey data used by the GPS receiver. (e.g. WGS-84) */ -#define GPSTAG_DESTLATITUDEREF 19 /* Indicates whether the latitude of the destination point is north or south latitude. */ -#define GPSTAG_DESTLATITUDE 20 /* Indicates the latitude of the destination point. */ -#define GPSTAG_DESTLONGITUDEREF 21 /* Indicates whether the longitude of the destination point is east or west longitude. */ -#define GPSTAG_DESTLONGITUDE 22 /* Indicates the longitude of the destination point. */ -#define GPSTAG_DESTBEARINGREF 23 /* Indicates the reference used for giving the bearing to the destination point. */ -#define GPSTAG_DESTBEARING 24 /* Indicates the bearing to the destination point. */ -#define GPSTAG_DESTDISTANCEREF 25 /* Indicates the unit used to express the distance to the destination point. */ -#define GPSTAG_DESTDISTANCE 26 /* Indicates the distance to the destination point. */ -#define GPSTAG_PROCESSINGMETHOD 27 /* A character string recording the name of the method used for location finding. */ -#define GPSTAG_AREAINFORMATION 28 /* A character string recording the name of the GPS area. */ -#define GPSTAG_DATESTAMP 29 /* A character string recording date and time information relative to UTC (Coordinated Universal Time). */ -#define GPSTAG_DIFFERENTIAL 30 /* Indicates whether differential correction is applied to the GPS receiver. */ -#define GPSTAG_GPSHPOSITIONINGERROR 31 /* Indicates horizontal positioning errors in meters. */ +#define GPSTAG_VERSIONID 0 /* Indicates the version of GPSInfoIFD. */ +#define GPSTAG_LATITUDEREF \ + 1 /* Indicates whether the latitude is north or south latitude. \ + */ +#define GPSTAG_LATITUDE 2 /* Indicates the latitude. */ +#define GPSTAG_LONGITUDEREF \ + 3 /* Indicates whether the longitude is east or west longitude. \ + */ +#define GPSTAG_LONGITUDE 4 /* Indicates the longitude. */ +#define GPSTAG_ALTITUDEREF \ + 5 /* Indicates the altitude used as the reference altitude. */ +#define GPSTAG_ALTITUDE \ + 6 /* Indicates the altitude based on the reference in \ + GPSAltitudeRef. */ +#define GPSTAG_TIMESTAMP \ + 7 /* Indicates the time as UTC (Coordinated Universal Time). */ +#define GPSTAG_SATELLITES \ + 8 /* Indicates the GPS satellites used for measurements. */ +#define GPSTAG_STATUS \ + 9 /* Indicates the status of the GPS receiver when the image is \ + recorded. */ +#define GPSTAG_MEASUREMODE \ + 10 /* Indicates the GPS measurement mode. */ +#define GPSTAG_DOP \ + 11 /* Indicates the GPS DOP (data degree of precision). */ +#define GPSTAG_SPEEDREF \ + 12 /* Indicates the unit used to express the GPS receiver speed of \ + movement. */ +#define GPSTAG_SPEED \ + 13 /* Indicates the speed of GPS receiver movement. */ +#define GPSTAG_TRACKREF \ + 14 /* Indicates the reference for giving the direction of GPS \ + receiver movement. */ +#define GPSTAG_TRACK \ + 15 /* Indicates the direction of GPS receiver movement. */ +#define GPSTAG_IMGDIRECTIONREF \ + 16 /* Indicates the reference for giving the direction of the image \ + when it is captured. */ +#define GPSTAG_IMGDIRECTION \ + 17 /* Indicates the direction of the image when it was captured. \ + */ +#define GPSTAG_MAPDATUM \ + 18 /* Indicates the geodetic survey data used by the GPS receiver. \ + (e.g. WGS-84) */ +#define GPSTAG_DESTLATITUDEREF \ + 19 /* Indicates whether the latitude of the destination point is \ + north or south latitude. */ +#define GPSTAG_DESTLATITUDE \ + 20 /* Indicates the latitude of the destination point. */ +#define GPSTAG_DESTLONGITUDEREF \ + 21 /* Indicates whether the longitude of the destination point is \ + east or west longitude. */ +#define GPSTAG_DESTLONGITUDE \ + 22 /* Indicates the longitude of the destination point. */ +#define GPSTAG_DESTBEARINGREF \ + 23 /* Indicates the reference used for giving the bearing to the \ + destination point. */ +#define GPSTAG_DESTBEARING \ + 24 /* Indicates the bearing to the destination point. */ +#define GPSTAG_DESTDISTANCEREF \ + 25 /* Indicates the unit used to express the distance to the \ + destination point. */ +#define GPSTAG_DESTDISTANCE \ + 26 /* Indicates the distance to the destination point. */ +#define GPSTAG_PROCESSINGMETHOD \ + 27 /* A character string recording the name of the method used for \ + location finding. */ +#define GPSTAG_AREAINFORMATION \ + 28 /* A character string recording the name of the GPS area. */ +#define GPSTAG_DATESTAMP \ + 29 /* A character string recording date and time information \ + relative to UTC (Coordinated Universal Time). */ +#define GPSTAG_DIFFERENTIAL \ + 30 /* Indicates whether differential correction is applied to the \ + GPS receiver. */ +#define GPSTAG_GPSHPOSITIONINGERROR \ + 31 /* Indicates horizontal positioning errors in meters. */ #endif /* _TIFF_ */ diff --git a/libtiff/tiffio.h b/libtiff/tiffio.h index a36e5a9c..df20f8bb 100644 --- a/libtiff/tiffio.h +++ b/libtiff/tiffio.h @@ -23,7 +23,7 @@ */ #ifndef _TIFFIO_ -#define _TIFFIO_ +#define _TIFFIO_ /* * TIFF I/O Library Definitions. @@ -65,17 +65,17 @@ typedef struct tiff TIFF; typedef TIFF_SSIZE_T tmsize_t; #define TIFF_TMSIZE_T_MAX (tmsize_t)(SIZE_MAX >> 1) -typedef uint64_t toff_t; /* file offset */ +typedef uint64_t toff_t; /* file offset */ /* the following are deprecated and should be replaced by their defining counterparts */ -typedef uint32_t ttag_t; /* directory tag */ -typedef uint16_t tdir_t; /* directory index */ -typedef uint16_t tsample_t; /* sample number */ -typedef uint32_t tstrile_t; /* strip or tile number */ -typedef tstrile_t tstrip_t; /* strip number */ -typedef tstrile_t ttile_t; /* tile number */ -typedef tmsize_t tsize_t; /* i/o size in bytes */ -typedef void* tdata_t; /* image data ref */ +typedef uint32_t ttag_t; /* directory tag */ +typedef uint16_t tdir_t; /* directory index */ +typedef uint16_t tsample_t; /* sample number */ +typedef uint32_t tstrile_t; /* strip or tile number */ +typedef tstrile_t tstrip_t; /* strip number */ +typedef tstrile_t ttile_t; /* tile number */ +typedef tmsize_t tsize_t; /* i/o size in bytes */ +typedef void *tdata_t; /* image data ref */ #if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32)) #define __WIN32__ @@ -89,21 +89,22 @@ typedef void* tdata_t; /* image data ref */ */ #if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows) -# if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && !defined(USE_WIN32_FILEIO) -# define AVOID_WIN32_FILEIO -# endif +#if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && \ + !defined(USE_WIN32_FILEIO) +#define AVOID_WIN32_FILEIO +#endif #endif #if defined(USE_WIN32_FILEIO) -# define VC_EXTRALEAN -# include <windows.h> -# ifdef __WIN32__ -DECLARE_HANDLE(thandle_t); /* Win32 file handle */ -# else -typedef HFILE thandle_t; /* client data handle */ -# endif /* __WIN32__ */ +#define VC_EXTRALEAN +#include <windows.h> +#ifdef __WIN32__ +DECLARE_HANDLE(thandle_t); /* Win32 file handle */ +#else +typedef HFILE thandle_t; /* client data handle */ +#endif /* __WIN32__ */ #else -typedef void* thandle_t; /* client data handle */ +typedef void *thandle_t; /* client data handle */ #endif /* USE_WIN32_FILEIO */ /* @@ -112,15 +113,15 @@ typedef void* thandle_t; /* client data handle */ * very large. Bit-or these flags to enable printing * multiple items. */ -#define TIFFPRINT_NONE 0x0 /* no extra info */ -#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ -#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ -#define TIFFPRINT_COLORMAP 0x4 /* colormap */ -#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ -#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ -#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ - -/* +#define TIFFPRINT_NONE 0x0 /* no extra info */ +#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ +#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ +#define TIFFPRINT_COLORMAP 0x4 /* colormap */ +#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ +#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ +#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ + +/* * Colour conversion stuff */ @@ -135,42 +136,45 @@ typedef void* thandle_t; /* client data handle */ /* Structure for holding information about a display device. */ -typedef unsigned char TIFFRGBValue; /* 8-bit samples */ - -typedef struct { - float d_mat[3][3]; /* XYZ -> luminance matrix */ - float d_YCR; /* Light o/p for reference white */ - float d_YCG; - float d_YCB; - uint32_t d_Vrwr; /* Pixel values for ref. white */ - uint32_t d_Vrwg; - uint32_t d_Vrwb; - float d_Y0R; /* Residual light for black pixel */ - float d_Y0G; - float d_Y0B; - float d_gammaR; /* Gamma values for the three guns */ - float d_gammaG; - float d_gammaB; +typedef unsigned char TIFFRGBValue; /* 8-bit samples */ + +typedef struct +{ + float d_mat[3][3]; /* XYZ -> luminance matrix */ + float d_YCR; /* Light o/p for reference white */ + float d_YCG; + float d_YCB; + uint32_t d_Vrwr; /* Pixel values for ref. white */ + uint32_t d_Vrwg; + uint32_t d_Vrwb; + float d_Y0R; /* Residual light for black pixel */ + float d_Y0G; + float d_Y0B; + float d_gammaR; /* Gamma values for the three guns */ + float d_gammaG; + float d_gammaB; } TIFFDisplay; -typedef struct { /* YCbCr->RGB support */ - TIFFRGBValue* clamptab; /* range clamping table */ - int* Cr_r_tab; - int* Cb_b_tab; - int32_t* Cr_g_tab; - int32_t* Cb_g_tab; - int32_t* Y_tab; +typedef struct +{ /* YCbCr->RGB support */ + TIFFRGBValue *clamptab; /* range clamping table */ + int *Cr_r_tab; + int *Cb_b_tab; + int32_t *Cr_g_tab; + int32_t *Cb_g_tab; + int32_t *Y_tab; } TIFFYCbCrToRGB; -typedef struct { /* CIE Lab 1976->RGB support */ - int range; /* Size of conversion table */ +typedef struct +{ /* CIE Lab 1976->RGB support */ + int range; /* Size of conversion table */ #define CIELABTORGB_TABLE_RANGE 1500 - float rstep, gstep, bstep; - float X0, Y0, Z0; /* Reference white point */ - TIFFDisplay display; - float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */ - float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */ - float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */ + float rstep, gstep, bstep; + float X0, Y0, Z0; /* Reference white point */ + TIFFDisplay display; + float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */ + float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */ + float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */ } TIFFCIELabToRGB; /* @@ -180,63 +184,66 @@ typedef struct _TIFFRGBAImage TIFFRGBAImage; /* * The image reading and conversion routines invoke * ``put routines'' to copy/image/whatever tiles of - * raw image data. A default set of routines are + * raw image data. A default set of routines are * provided to convert/copy raw image data to 8-bit * packed ABGR format rasters. Applications can supply * alternate routines that unpack the data into a * different format or, for example, unpack the data * and draw the unpacked raster on the display. */ -typedef void (*tileContigRoutine) - (TIFFRGBAImage*, uint32_t*, uint32_t, uint32_t, uint32_t, uint32_t, int32_t, int32_t, - unsigned char*); -typedef void (*tileSeparateRoutine) - (TIFFRGBAImage*, uint32_t*, uint32_t, uint32_t, uint32_t, uint32_t, int32_t, int32_t, - unsigned char*, unsigned char*, unsigned char*, unsigned char*); +typedef void (*tileContigRoutine)(TIFFRGBAImage *, uint32_t *, uint32_t, + uint32_t, uint32_t, uint32_t, int32_t, + int32_t, unsigned char *); +typedef void (*tileSeparateRoutine)(TIFFRGBAImage *, uint32_t *, uint32_t, + uint32_t, uint32_t, uint32_t, int32_t, + int32_t, unsigned char *, unsigned char *, + unsigned char *, unsigned char *); /* * RGBA-reader state. */ -struct _TIFFRGBAImage { - TIFF* tif; /* image handle */ - int stoponerr; /* stop on read error */ - int isContig; /* data is packed/separate */ - int alpha; /* type of alpha data present */ - uint32_t width; /* image width */ - uint32_t height; /* image height */ - uint16_t bitspersample; /* image bits/sample */ - uint16_t samplesperpixel; /* image samples/pixel */ - uint16_t orientation; /* image orientation */ - uint16_t req_orientation; /* requested orientation */ - uint16_t photometric; /* image photometric interp */ - uint16_t* redcmap; /* colormap palette */ - uint16_t* greencmap; - uint16_t* bluecmap; - /* get image data routine */ - int (*get)(TIFFRGBAImage*, uint32_t*, uint32_t, uint32_t); - /* put decoded strip/tile */ - union { - void (*any)(TIFFRGBAImage*); - tileContigRoutine contig; - tileSeparateRoutine separate; - } put; - TIFFRGBValue* Map; /* sample mapping array */ - uint32_t** BWmap; /* black&white map */ - uint32_t** PALmap; /* palette image map */ - TIFFYCbCrToRGB* ycbcr; /* YCbCr conversion state */ - TIFFCIELabToRGB* cielab; /* CIE L*a*b conversion state */ - - uint8_t* UaToAa; /* Unassociated alpha to associated alpha conversion LUT */ - uint8_t* Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */ - - int row_offset; - int col_offset; +struct _TIFFRGBAImage +{ + TIFF *tif; /* image handle */ + int stoponerr; /* stop on read error */ + int isContig; /* data is packed/separate */ + int alpha; /* type of alpha data present */ + uint32_t width; /* image width */ + uint32_t height; /* image height */ + uint16_t bitspersample; /* image bits/sample */ + uint16_t samplesperpixel; /* image samples/pixel */ + uint16_t orientation; /* image orientation */ + uint16_t req_orientation; /* requested orientation */ + uint16_t photometric; /* image photometric interp */ + uint16_t *redcmap; /* colormap palette */ + uint16_t *greencmap; + uint16_t *bluecmap; + /* get image data routine */ + int (*get)(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); + /* put decoded strip/tile */ + union + { + void (*any)(TIFFRGBAImage *); + tileContigRoutine contig; + tileSeparateRoutine separate; + } put; + TIFFRGBValue *Map; /* sample mapping array */ + uint32_t **BWmap; /* black&white map */ + uint32_t **PALmap; /* palette image map */ + TIFFYCbCrToRGB *ycbcr; /* YCbCr conversion state */ + TIFFCIELabToRGB *cielab; /* CIE L*a*b conversion state */ + + uint8_t *UaToAa; /* Unassociated alpha to associated alpha conversion LUT */ + uint8_t *Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */ + + int row_offset; + int col_offset; }; /* * Macros for extracting components from the * packed ABGR form returned by TIFFReadRGBAImage. */ -#define TIFFGetR(abgr) ((abgr) & 0xff) +#define TIFFGetR(abgr) ((abgr)&0xff) #define TIFFGetG(abgr) (((abgr) >> 8) & 0xff) #define TIFFGetB(abgr) (((abgr) >> 16) & 0xff) #define TIFFGetA(abgr) (((abgr) >> 24) & 0xff) @@ -248,15 +255,16 @@ struct _TIFFRGBAImage { * More codecs may be registered through calls to the library * and/or the builtin implementations may be overridden. */ -typedef int (*TIFFInitMethod)(TIFF*, int); -typedef struct { - char* name; - uint16_t scheme; - TIFFInitMethod init; +typedef int (*TIFFInitMethod)(TIFF *, int); +typedef struct +{ + char *name; + uint16_t scheme; + TIFFInitMethod init; } TIFFCodec; -#include <stdio.h> #include <stdarg.h> +#include <stdio.h> /* share internal LogLuv conversion routines? */ #ifndef LOGLUV_PUBLIC @@ -264,327 +272,374 @@ typedef struct { #endif #if defined(__GNUC__) || defined(__attribute__) -# define TIFF_ATTRIBUTE(x) __attribute__(x) +#define TIFF_ATTRIBUTE(x) __attribute__(x) #else -# define TIFF_ATTRIBUTE(x) /*nothing*/ +#define TIFF_ATTRIBUTE(x) /*nothing*/ #endif #if defined(c_plusplus) || defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -typedef void (*TIFFErrorHandler)(const char*, const char*, va_list); -typedef void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list); -typedef int (*TIFFErrorHandlerExtR)(TIFF*, void* user_data, const char*, const char*, va_list); -typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void*, tmsize_t); -typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); -typedef int (*TIFFCloseProc)(thandle_t); -typedef toff_t (*TIFFSizeProc)(thandle_t); -typedef int (*TIFFMapFileProc)(thandle_t, void** base, toff_t* size); -typedef void (*TIFFUnmapFileProc)(thandle_t, void* base, toff_t size); -typedef void (*TIFFExtendProc)(TIFF*); - -extern const char* TIFFGetVersion(void); - -extern const TIFFCodec* TIFFFindCODEC(uint16_t); -extern TIFFCodec* TIFFRegisterCODEC(uint16_t, const char*, TIFFInitMethod); -extern void TIFFUnRegisterCODEC(TIFFCodec*); -extern int TIFFIsCODECConfigured(uint16_t); -extern TIFFCodec* TIFFGetConfiguredCODECs(void); - -/* - * Auxiliary functions. - */ - -extern void* _TIFFmalloc(tmsize_t s); -extern void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz); -extern void* _TIFFrealloc(void* p, tmsize_t s); -extern void _TIFFmemset(void* p, int v, tmsize_t c); -extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c); -extern int _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c); -extern void _TIFFfree(void* p); - -/* -** Stuff, related to tag handling and creating custom tags. -*/ -extern int TIFFGetTagListCount( TIFF * ); -extern uint32_t TIFFGetTagListEntry(TIFF *, int tag_index ); - -#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */ -#define TIFF_VARIABLE -1 /* marker for variable length tags */ -#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */ -#define TIFF_VARIABLE2 -3 /* marker for uint32_t var-length tags */ - -#define FIELD_CUSTOM 65 - -typedef struct _TIFFField TIFFField; -typedef struct _TIFFFieldArray TIFFFieldArray; - -extern const TIFFField* TIFFFindField(TIFF *, uint32_t, TIFFDataType); -extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32_t); -extern const TIFFField* TIFFFieldWithName(TIFF*, const char *); - -extern uint32_t TIFFFieldTag(const TIFFField*); -extern const char* TIFFFieldName(const TIFFField*); -extern TIFFDataType TIFFFieldDataType(const TIFFField*); -extern int TIFFFieldPassCount(const TIFFField*); -extern int TIFFFieldReadCount(const TIFFField*); -extern int TIFFFieldWriteCount(const TIFFField*); -extern int TIFFFieldSetGetSize(const TIFFField*); /* returns internal storage size of TIFFSetGetFieldType in bytes. */ -extern int TIFFFieldSetGetCountSize(const TIFFField*); /* returns size of count parameter 0=none, 2=uint16_t, 4=uint32_t */ -extern int TIFFFieldIsAnonymous(const TIFFField *); - -typedef int (*TIFFVSetMethod)(TIFF*, uint32_t, va_list); -typedef int (*TIFFVGetMethod)(TIFF*, uint32_t, va_list); -typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long); - -typedef struct { - TIFFVSetMethod vsetfield; /* tag set routine */ - TIFFVGetMethod vgetfield; /* tag get routine */ - TIFFPrintMethod printdir; /* directory print routine */ -} TIFFTagMethods; - -extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *); -extern void *TIFFGetClientInfo(TIFF *, const char *); -extern void TIFFSetClientInfo(TIFF *, void *, const char *); - -extern void TIFFCleanup(TIFF* tif); -extern void TIFFClose(TIFF* tif); -extern int TIFFFlush(TIFF* tif); -extern int TIFFFlushData(TIFF* tif); -extern int TIFFGetField(TIFF* tif, uint32_t tag, ...); -extern int TIFFVGetField(TIFF* tif, uint32_t tag, va_list ap); -extern int TIFFGetFieldDefaulted(TIFF* tif, uint32_t tag, ...); -extern int TIFFVGetFieldDefaulted(TIFF* tif, uint32_t tag, va_list ap); -extern int TIFFReadDirectory(TIFF* tif); -extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray); -extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff); -extern int TIFFReadGPSDirectory(TIFF* tif, toff_t diroff); -extern uint64_t TIFFScanlineSize64(TIFF* tif); -extern tmsize_t TIFFScanlineSize(TIFF* tif); -extern uint64_t TIFFRasterScanlineSize64(TIFF* tif); -extern tmsize_t TIFFRasterScanlineSize(TIFF* tif); -extern uint64_t TIFFStripSize64(TIFF* tif); -extern tmsize_t TIFFStripSize(TIFF* tif); -extern uint64_t TIFFRawStripSize64(TIFF* tif, uint32_t strip); -extern tmsize_t TIFFRawStripSize(TIFF* tif, uint32_t strip); -extern uint64_t TIFFVStripSize64(TIFF* tif, uint32_t nrows); -extern tmsize_t TIFFVStripSize(TIFF* tif, uint32_t nrows); -extern uint64_t TIFFTileRowSize64(TIFF* tif); -extern tmsize_t TIFFTileRowSize(TIFF* tif); -extern uint64_t TIFFTileSize64(TIFF* tif); -extern tmsize_t TIFFTileSize(TIFF* tif); -extern uint64_t TIFFVTileSize64(TIFF* tif, uint32_t nrows); -extern tmsize_t TIFFVTileSize(TIFF* tif, uint32_t nrows); -extern uint32_t TIFFDefaultStripSize(TIFF* tif, uint32_t request); -extern void TIFFDefaultTileSize(TIFF*, uint32_t*, uint32_t*); -extern int TIFFFileno(TIFF*); -extern int TIFFSetFileno(TIFF*, int); -extern thandle_t TIFFClientdata(TIFF*); -extern thandle_t TIFFSetClientdata(TIFF*, thandle_t); -extern int TIFFGetMode(TIFF*); -extern int TIFFSetMode(TIFF*, int); -extern int TIFFIsTiled(TIFF*); -extern int TIFFIsByteSwapped(TIFF*); -extern int TIFFIsUpSampled(TIFF*); -extern int TIFFIsMSB2LSB(TIFF*); -extern int TIFFIsBigEndian(TIFF*); -extern int TIFFIsBigTIFF(TIFF*); -extern TIFFReadWriteProc TIFFGetReadProc(TIFF*); -extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*); -extern TIFFSeekProc TIFFGetSeekProc(TIFF*); -extern TIFFCloseProc TIFFGetCloseProc(TIFF*); -extern TIFFSizeProc TIFFGetSizeProc(TIFF*); -extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*); -extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*); -extern uint32_t TIFFCurrentRow(TIFF*); -extern uint16_t TIFFCurrentDirectory(TIFF*); -extern uint16_t TIFFNumberOfDirectories(TIFF*); -extern uint64_t TIFFCurrentDirOffset(TIFF*); -extern uint32_t TIFFCurrentStrip(TIFF*); -extern uint32_t TIFFCurrentTile(TIFF* tif); -extern int TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size); -extern int TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size); -extern int TIFFSetupStrips(TIFF *); -extern int TIFFWriteCheck(TIFF*, int, const char *); -extern void TIFFFreeDirectory(TIFF*); -extern int TIFFCreateDirectory(TIFF*); -extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*); -extern int TIFFCreateEXIFDirectory(TIFF*); -extern int TIFFCreateGPSDirectory(TIFF*); -extern int TIFFLastDirectory(TIFF*); -extern int TIFFSetDirectory(TIFF*, uint16_t); -extern int TIFFSetSubDirectory(TIFF*, uint64_t); -extern int TIFFUnlinkDirectory(TIFF*, uint16_t); -extern int TIFFSetField(TIFF*, uint32_t, ...); -extern int TIFFVSetField(TIFF*, uint32_t, va_list); -extern int TIFFUnsetField(TIFF*, uint32_t); -extern int TIFFWriteDirectory(TIFF *); -extern int TIFFWriteCustomDirectory(TIFF *, uint64_t *); -extern int TIFFCheckpointDirectory(TIFF *); -extern int TIFFRewriteDirectory(TIFF *); -extern int TIFFDeferStrileArrayWriting(TIFF *); -extern int TIFFForceStrileArrayWriting(TIFF* ); + typedef void (*TIFFErrorHandler)(const char *, const char *, va_list); + typedef void (*TIFFErrorHandlerExt)(thandle_t, const char *, const char *, + va_list); + typedef int (*TIFFErrorHandlerExtR)(TIFF *, void *user_data, const char *, + const char *, va_list); + typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void *, tmsize_t); + typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); + typedef int (*TIFFCloseProc)(thandle_t); + typedef toff_t (*TIFFSizeProc)(thandle_t); + typedef int (*TIFFMapFileProc)(thandle_t, void **base, toff_t *size); + typedef void (*TIFFUnmapFileProc)(thandle_t, void *base, toff_t size); + typedef void (*TIFFExtendProc)(TIFF *); + + extern const char *TIFFGetVersion(void); + + extern const TIFFCodec *TIFFFindCODEC(uint16_t); + extern TIFFCodec *TIFFRegisterCODEC(uint16_t, const char *, TIFFInitMethod); + extern void TIFFUnRegisterCODEC(TIFFCodec *); + extern int TIFFIsCODECConfigured(uint16_t); + extern TIFFCodec *TIFFGetConfiguredCODECs(void); + + /* + * Auxiliary functions. + */ + + extern void *_TIFFmalloc(tmsize_t s); + extern void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz); + extern void *_TIFFrealloc(void *p, tmsize_t s); + extern void _TIFFmemset(void *p, int v, tmsize_t c); + extern void _TIFFmemcpy(void *d, const void *s, tmsize_t c); + extern int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c); + extern void _TIFFfree(void *p); + + /* + ** Stuff, related to tag handling and creating custom tags. + */ + extern int TIFFGetTagListCount(TIFF *); + extern uint32_t TIFFGetTagListEntry(TIFF *, int tag_index); + +#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */ +#define TIFF_VARIABLE -1 /* marker for variable length tags */ +#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */ +#define TIFF_VARIABLE2 -3 /* marker for uint32_t var-length tags */ + +#define FIELD_CUSTOM 65 + + typedef struct _TIFFField TIFFField; + typedef struct _TIFFFieldArray TIFFFieldArray; + + extern const TIFFField *TIFFFindField(TIFF *, uint32_t, TIFFDataType); + extern const TIFFField *TIFFFieldWithTag(TIFF *, uint32_t); + extern const TIFFField *TIFFFieldWithName(TIFF *, const char *); + + extern uint32_t TIFFFieldTag(const TIFFField *); + extern const char *TIFFFieldName(const TIFFField *); + extern TIFFDataType TIFFFieldDataType(const TIFFField *); + extern int TIFFFieldPassCount(const TIFFField *); + extern int TIFFFieldReadCount(const TIFFField *); + extern int TIFFFieldWriteCount(const TIFFField *); + extern int + TIFFFieldSetGetSize(const TIFFField *); /* returns internal storage size of + TIFFSetGetFieldType in bytes. */ + extern int TIFFFieldSetGetCountSize( + const TIFFField *); /* returns size of count parameter 0=none, + 2=uint16_t, 4=uint32_t */ + extern int TIFFFieldIsAnonymous(const TIFFField *); + + typedef int (*TIFFVSetMethod)(TIFF *, uint32_t, va_list); + typedef int (*TIFFVGetMethod)(TIFF *, uint32_t, va_list); + typedef void (*TIFFPrintMethod)(TIFF *, FILE *, long); + + typedef struct + { + TIFFVSetMethod vsetfield; /* tag set routine */ + TIFFVGetMethod vgetfield; /* tag get routine */ + TIFFPrintMethod printdir; /* directory print routine */ + } TIFFTagMethods; + + extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *); + extern void *TIFFGetClientInfo(TIFF *, const char *); + extern void TIFFSetClientInfo(TIFF *, void *, const char *); + + extern void TIFFCleanup(TIFF *tif); + extern void TIFFClose(TIFF *tif); + extern int TIFFFlush(TIFF *tif); + extern int TIFFFlushData(TIFF *tif); + extern int TIFFGetField(TIFF *tif, uint32_t tag, ...); + extern int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap); + extern int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...); + extern int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap); + extern int TIFFReadDirectory(TIFF *tif); + extern int TIFFReadCustomDirectory(TIFF *tif, toff_t diroff, + const TIFFFieldArray *infoarray); + extern int TIFFReadEXIFDirectory(TIFF *tif, toff_t diroff); + extern int TIFFReadGPSDirectory(TIFF *tif, toff_t diroff); + extern uint64_t TIFFScanlineSize64(TIFF *tif); + extern tmsize_t TIFFScanlineSize(TIFF *tif); + extern uint64_t TIFFRasterScanlineSize64(TIFF *tif); + extern tmsize_t TIFFRasterScanlineSize(TIFF *tif); + extern uint64_t TIFFStripSize64(TIFF *tif); + extern tmsize_t TIFFStripSize(TIFF *tif); + extern uint64_t TIFFRawStripSize64(TIFF *tif, uint32_t strip); + extern tmsize_t TIFFRawStripSize(TIFF *tif, uint32_t strip); + extern uint64_t TIFFVStripSize64(TIFF *tif, uint32_t nrows); + extern tmsize_t TIFFVStripSize(TIFF *tif, uint32_t nrows); + extern uint64_t TIFFTileRowSize64(TIFF *tif); + extern tmsize_t TIFFTileRowSize(TIFF *tif); + extern uint64_t TIFFTileSize64(TIFF *tif); + extern tmsize_t TIFFTileSize(TIFF *tif); + extern uint64_t TIFFVTileSize64(TIFF *tif, uint32_t nrows); + extern tmsize_t TIFFVTileSize(TIFF *tif, uint32_t nrows); + extern uint32_t TIFFDefaultStripSize(TIFF *tif, uint32_t request); + extern void TIFFDefaultTileSize(TIFF *, uint32_t *, uint32_t *); + extern int TIFFFileno(TIFF *); + extern int TIFFSetFileno(TIFF *, int); + extern thandle_t TIFFClientdata(TIFF *); + extern thandle_t TIFFSetClientdata(TIFF *, thandle_t); + extern int TIFFGetMode(TIFF *); + extern int TIFFSetMode(TIFF *, int); + extern int TIFFIsTiled(TIFF *); + extern int TIFFIsByteSwapped(TIFF *); + extern int TIFFIsUpSampled(TIFF *); + extern int TIFFIsMSB2LSB(TIFF *); + extern int TIFFIsBigEndian(TIFF *); + extern int TIFFIsBigTIFF(TIFF *); + extern TIFFReadWriteProc TIFFGetReadProc(TIFF *); + extern TIFFReadWriteProc TIFFGetWriteProc(TIFF *); + extern TIFFSeekProc TIFFGetSeekProc(TIFF *); + extern TIFFCloseProc TIFFGetCloseProc(TIFF *); + extern TIFFSizeProc TIFFGetSizeProc(TIFF *); + extern TIFFMapFileProc TIFFGetMapFileProc(TIFF *); + extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *); + extern uint32_t TIFFCurrentRow(TIFF *); + extern uint16_t TIFFCurrentDirectory(TIFF *); + extern uint16_t TIFFNumberOfDirectories(TIFF *); + extern uint64_t TIFFCurrentDirOffset(TIFF *); + extern uint32_t TIFFCurrentStrip(TIFF *); + extern uint32_t TIFFCurrentTile(TIFF *tif); + extern int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size); + extern int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size); + extern int TIFFSetupStrips(TIFF *); + extern int TIFFWriteCheck(TIFF *, int, const char *); + extern void TIFFFreeDirectory(TIFF *); + extern int TIFFCreateDirectory(TIFF *); + extern int TIFFCreateCustomDirectory(TIFF *, const TIFFFieldArray *); + extern int TIFFCreateEXIFDirectory(TIFF *); + extern int TIFFCreateGPSDirectory(TIFF *); + extern int TIFFLastDirectory(TIFF *); + extern int TIFFSetDirectory(TIFF *, uint16_t); + extern int TIFFSetSubDirectory(TIFF *, uint64_t); + extern int TIFFUnlinkDirectory(TIFF *, uint16_t); + extern int TIFFSetField(TIFF *, uint32_t, ...); + extern int TIFFVSetField(TIFF *, uint32_t, va_list); + extern int TIFFUnsetField(TIFF *, uint32_t); + extern int TIFFWriteDirectory(TIFF *); + extern int TIFFWriteCustomDirectory(TIFF *, uint64_t *); + extern int TIFFCheckpointDirectory(TIFF *); + extern int TIFFRewriteDirectory(TIFF *); + extern int TIFFDeferStrileArrayWriting(TIFF *); + extern int TIFFForceStrileArrayWriting(TIFF *); #if defined(c_plusplus) || defined(__cplusplus) -extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0); -extern int TIFFReadScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample = 0); -extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample = 0); -extern int TIFFReadRGBAImage(TIFF*, uint32_t, uint32_t, uint32_t*, int = 0); -extern int TIFFReadRGBAImageOriented(TIFF*, uint32_t, uint32_t, uint32_t*, - int = ORIENTATION_BOTLEFT, int = 0); + extern void TIFFPrintDirectory(TIFF *, FILE *, long = 0); + extern int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, + uint16_t sample = 0); + extern int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, + uint16_t sample = 0); + extern int TIFFReadRGBAImage(TIFF *, uint32_t, uint32_t, uint32_t *, + int = 0); + extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *, + int = ORIENTATION_BOTLEFT, int = 0); #else -extern void TIFFPrintDirectory(TIFF*, FILE*, long); -extern int TIFFReadScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample); -extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32_t row, uint16_t sample); -extern int TIFFReadRGBAImage(TIFF*, uint32_t, uint32_t, uint32_t*, int); -extern int TIFFReadRGBAImageOriented(TIFF*, uint32_t, uint32_t, uint32_t*, int, int); +extern void TIFFPrintDirectory(TIFF *, FILE *, long); +extern int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, + uint16_t sample); +extern int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, + uint16_t sample); +extern int TIFFReadRGBAImage(TIFF *, uint32_t, uint32_t, uint32_t *, int); +extern int TIFFReadRGBAImageOriented(TIFF *, uint32_t, uint32_t, uint32_t *, + int, int); #endif -extern int TIFFReadRGBAStrip(TIFF*, uint32_t, uint32_t * ); -extern int TIFFReadRGBATile(TIFF*, uint32_t, uint32_t, uint32_t * ); -extern int TIFFReadRGBAStripExt(TIFF*, uint32_t, uint32_t *, int stop_on_error ); -extern int TIFFReadRGBATileExt(TIFF*, uint32_t, uint32_t, uint32_t *, int stop_on_error ); -extern int TIFFRGBAImageOK(TIFF*, char [1024]); -extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]); -extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32_t*, uint32_t, uint32_t); -extern void TIFFRGBAImageEnd(TIFFRGBAImage*); - -extern const char* TIFFFileName(TIFF*); -extern const char* TIFFSetFileName(TIFF*, const char *); -extern void TIFFError(const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,2,3))); -extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,3,4))); -extern void TIFFWarning(const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,2,3))); -extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,3,4))); -extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); -extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt); -extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); -extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt); - -extern void TIFFWarningExtR(TIFF*, const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,3,4))); -extern void TIFFErrorExtR(TIFF*, const char*, const char*, ...) TIFF_ATTRIBUTE((__format__ (__printf__,3,4))); - -typedef struct TIFFOpenOptions TIFFOpenOptions; -extern TIFFOpenOptions* TIFFOpenOptionsAlloc(void); -extern void TIFFOpenOptionsFree(TIFFOpenOptions*); -extern void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions* opts, tmsize_t max_single_mem_alloc); -extern void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions* opts, TIFFErrorHandlerExtR handler, void* errorhandler_user_data); -extern void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions* opts, TIFFErrorHandlerExtR handler, void* warnhandler_user_data); - -extern TIFF* TIFFOpen(const char*, const char*); -extern TIFF* TIFFOpenExt(const char*, const char*, TIFFOpenOptions* opts); -# ifdef __WIN32__ -extern TIFF* TIFFOpenW(const wchar_t*, const char*); -extern TIFF* TIFFOpenWExt(const wchar_t*, const char*, TIFFOpenOptions* opts); -# endif /* __WIN32__ */ -extern TIFF* TIFFFdOpen(int, const char*, const char*); -extern TIFF* TIFFFdOpenExt(int, const char*, const char*, TIFFOpenOptions* opts); -extern TIFF* TIFFClientOpen(const char*, const char*, - thandle_t, - TIFFReadWriteProc, TIFFReadWriteProc, - TIFFSeekProc, TIFFCloseProc, - TIFFSizeProc, - TIFFMapFileProc, TIFFUnmapFileProc); -extern TIFF* TIFFClientOpenExt(const char*, const char*, - thandle_t, - TIFFReadWriteProc, TIFFReadWriteProc, - TIFFSeekProc, TIFFCloseProc, - TIFFSizeProc, - TIFFMapFileProc, TIFFUnmapFileProc, - TIFFOpenOptions* opts); -extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); -extern uint32_t TIFFComputeTile(TIFF* tif, uint32_t x, uint32_t y, uint32_t z, uint16_t s); -extern int TIFFCheckTile(TIFF* tif, uint32_t x, uint32_t y, uint32_t z, uint16_t s); -extern uint32_t TIFFNumberOfTiles(TIFF*); -extern tmsize_t TIFFReadTile(TIFF* tif, void* buf, uint32_t x, uint32_t y, uint32_t z, uint16_t s); -extern tmsize_t TIFFWriteTile(TIFF* tif, void* buf, uint32_t x, uint32_t y, uint32_t z, uint16_t s); -extern uint32_t TIFFComputeStrip(TIFF*, uint32_t, uint16_t); -extern uint32_t TIFFNumberOfStrips(TIFF*); -extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32_t strip, void* buf, tmsize_t size); -extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32_t strip, void* buf, tmsize_t size); -extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32_t tile, void* buf, tmsize_t size); -extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32_t tile, void* buf, tmsize_t size); -extern int TIFFReadFromUserBuffer(TIFF* tif, uint32_t strile, - void* inbuf, tmsize_t insize, - void* outbuf, tmsize_t outsize); -extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc); -extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32_t strip, void* data, tmsize_t cc); -extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc); -extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32_t tile, void* data, tmsize_t cc); -extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths within TIFF file. */ -extern void TIFFSetWriteOffset(TIFF* tif, toff_t off); -extern void TIFFSwabShort(uint16_t*); -extern void TIFFSwabLong(uint32_t*); -extern void TIFFSwabLong8(uint64_t*); -extern void TIFFSwabFloat(float*); -extern void TIFFSwabDouble(double*); -extern void TIFFSwabArrayOfShort(uint16_t* wp, tmsize_t n); -extern void TIFFSwabArrayOfTriples(uint8_t* tp, tmsize_t n); -extern void TIFFSwabArrayOfLong(uint32_t* lp, tmsize_t n); -extern void TIFFSwabArrayOfLong8(uint64_t* lp, tmsize_t n); -extern void TIFFSwabArrayOfFloat(float* fp, tmsize_t n); -extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n); -extern void TIFFReverseBits(uint8_t* cp, tmsize_t n); -extern const unsigned char* TIFFGetBitRevTable(int); - -extern uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile); -extern uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile); -extern uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, int *pbErr); -extern uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, int *pbErr); + extern int TIFFReadRGBAStrip(TIFF *, uint32_t, uint32_t *); + extern int TIFFReadRGBATile(TIFF *, uint32_t, uint32_t, uint32_t *); + extern int TIFFReadRGBAStripExt(TIFF *, uint32_t, uint32_t *, + int stop_on_error); + extern int TIFFReadRGBATileExt(TIFF *, uint32_t, uint32_t, uint32_t *, + int stop_on_error); + extern int TIFFRGBAImageOK(TIFF *, char[1024]); + extern int TIFFRGBAImageBegin(TIFFRGBAImage *, TIFF *, int, char[1024]); + extern int TIFFRGBAImageGet(TIFFRGBAImage *, uint32_t *, uint32_t, + uint32_t); + extern void TIFFRGBAImageEnd(TIFFRGBAImage *); + + extern const char *TIFFFileName(TIFF *); + extern const char *TIFFSetFileName(TIFF *, const char *); + extern void TIFFError(const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 2, 3))); + extern void TIFFErrorExt(thandle_t, const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); + extern void TIFFWarning(const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 2, 3))); + extern void TIFFWarningExt(thandle_t, const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); + extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); + extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt); + extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); + extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt); + + extern void TIFFWarningExtR(TIFF *, const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); + extern void TIFFErrorExtR(TIFF *, const char *, const char *, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 3, 4))); + + typedef struct TIFFOpenOptions TIFFOpenOptions; + extern TIFFOpenOptions *TIFFOpenOptionsAlloc(void); + extern void TIFFOpenOptionsFree(TIFFOpenOptions *); + extern void + TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts, + tmsize_t max_single_mem_alloc); + extern void + TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts, + TIFFErrorHandlerExtR handler, + void *errorhandler_user_data); + extern void + TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts, + TIFFErrorHandlerExtR handler, + void *warnhandler_user_data); + + extern TIFF *TIFFOpen(const char *, const char *); + extern TIFF *TIFFOpenExt(const char *, const char *, TIFFOpenOptions *opts); +#ifdef __WIN32__ + extern TIFF *TIFFOpenW(const wchar_t *, const char *); + extern TIFF *TIFFOpenWExt(const wchar_t *, const char *, + TIFFOpenOptions *opts); +#endif /* __WIN32__ */ + extern TIFF *TIFFFdOpen(int, const char *, const char *); + extern TIFF *TIFFFdOpenExt(int, const char *, const char *, + TIFFOpenOptions *opts); + extern TIFF *TIFFClientOpen(const char *, const char *, thandle_t, + TIFFReadWriteProc, TIFFReadWriteProc, + TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, + TIFFMapFileProc, TIFFUnmapFileProc); + extern TIFF *TIFFClientOpenExt(const char *, const char *, thandle_t, + TIFFReadWriteProc, TIFFReadWriteProc, + TIFFSeekProc, TIFFCloseProc, TIFFSizeProc, + TIFFMapFileProc, TIFFUnmapFileProc, + TIFFOpenOptions *opts); + extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); + extern uint32_t TIFFComputeTile(TIFF *tif, uint32_t x, uint32_t y, + uint32_t z, uint16_t s); + extern int TIFFCheckTile(TIFF *tif, uint32_t x, uint32_t y, uint32_t z, + uint16_t s); + extern uint32_t TIFFNumberOfTiles(TIFF *); + extern tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, + uint32_t z, uint16_t s); + extern tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, + uint32_t z, uint16_t s); + extern uint32_t TIFFComputeStrip(TIFF *, uint32_t, uint16_t); + extern uint32_t TIFFNumberOfStrips(TIFF *); + extern tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf, + tmsize_t size); + extern tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf, + tmsize_t size); + extern tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, + tmsize_t size); + extern tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, + tmsize_t size); + extern int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf, + tmsize_t insize, void *outbuf, + tmsize_t outsize); + extern tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data, + tmsize_t cc); + extern tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, + tmsize_t cc); + extern tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, + tmsize_t cc); + extern tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, + tmsize_t cc); + extern int TIFFDataWidth( + TIFFDataType); /* table of tag datatype widths within TIFF file. */ + extern void TIFFSetWriteOffset(TIFF *tif, toff_t off); + extern void TIFFSwabShort(uint16_t *); + extern void TIFFSwabLong(uint32_t *); + extern void TIFFSwabLong8(uint64_t *); + extern void TIFFSwabFloat(float *); + extern void TIFFSwabDouble(double *); + extern void TIFFSwabArrayOfShort(uint16_t *wp, tmsize_t n); + extern void TIFFSwabArrayOfTriples(uint8_t *tp, tmsize_t n); + extern void TIFFSwabArrayOfLong(uint32_t *lp, tmsize_t n); + extern void TIFFSwabArrayOfLong8(uint64_t *lp, tmsize_t n); + extern void TIFFSwabArrayOfFloat(float *fp, tmsize_t n); + extern void TIFFSwabArrayOfDouble(double *dp, tmsize_t n); + extern void TIFFReverseBits(uint8_t *cp, tmsize_t n); + extern const unsigned char *TIFFGetBitRevTable(int); + + extern uint64_t TIFFGetStrileOffset(TIFF *tif, uint32_t strile); + extern uint64_t TIFFGetStrileByteCount(TIFF *tif, uint32_t strile); + extern uint64_t TIFFGetStrileOffsetWithErr(TIFF *tif, uint32_t strile, + int *pbErr); + extern uint64_t TIFFGetStrileByteCountWithErr(TIFF *tif, uint32_t strile, + int *pbErr); #ifdef LOGLUV_PUBLIC -#define U_NEU 0.210526316 -#define V_NEU 0.473684211 -#define UVSCALE 410. -extern double LogL16toY(int); -extern double LogL10toY(int); -extern void XYZtoRGB24(float*, uint8_t*); -extern int uv_decode(double*, double*, int); -extern void LogLuv24toXYZ(uint32_t, float*); -extern void LogLuv32toXYZ(uint32_t, float*); +#define U_NEU 0.210526316 +#define V_NEU 0.473684211 +#define UVSCALE 410. + extern double LogL16toY(int); + extern double LogL10toY(int); + extern void XYZtoRGB24(float *, uint8_t *); + extern int uv_decode(double *, double *, int); + extern void LogLuv24toXYZ(uint32_t, float *); + extern void LogLuv32toXYZ(uint32_t, float *); #if defined(c_plusplus) || defined(__cplusplus) -extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER); -extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER); -extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER); -extern uint32_t LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER); -extern uint32_t LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER); + extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER); + extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER); + extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER); + extern uint32_t LogLuv24fromXYZ(float *, int = SGILOGENCODE_NODITHER); + extern uint32_t LogLuv32fromXYZ(float *, int = SGILOGENCODE_NODITHER); #else -extern int LogL16fromY(double, int); -extern int LogL10fromY(double, int); -extern int uv_encode(double, double, int); -extern uint32_t LogLuv24fromXYZ(float*, int); -extern uint32_t LogLuv32fromXYZ(float*, int); + extern int LogL16fromY(double, int); + extern int LogL10fromY(double, int); + extern int uv_encode(double, double, int); + extern uint32_t LogLuv24fromXYZ(float *, int); + extern uint32_t LogLuv32fromXYZ(float *, int); #endif #endif /* LOGLUV_PUBLIC */ -extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, const TIFFDisplay *, float*); -extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32_t, int32_t, int32_t, - float *, float *, float *); -extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, - uint32_t *, uint32_t *, uint32_t *); - -extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*); -extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32_t, int32_t, int32_t, - uint32_t *, uint32_t *, uint32_t *); + extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB *, const TIFFDisplay *, + float *); + extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32_t, int32_t, int32_t, + float *, float *, float *); + extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float, uint32_t *, + uint32_t *, uint32_t *); + + extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *, float *, float *); + extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32_t, int32_t, int32_t, + uint32_t *, uint32_t *, uint32_t *); + + /**************************************************************************** + * O B S O L E T E D I N T E R F A C E S + * + * Don't use this stuff in your applications, it may be removed in the + *future libtiff versions. + ****************************************************************************/ + typedef struct + { + ttag_t field_tag; /* field's tag */ + short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ + short field_writecount; /* write count/TIFF_VARIABLE */ + TIFFDataType field_type; /* type of associated data */ + unsigned short field_bit; /* bit in fieldsset bit vector */ + unsigned char field_oktochange; /* if true, can change while writing */ + unsigned char field_passcount; /* if true, pass dir count on set */ + char *field_name; /* ASCII name */ + } TIFFFieldInfo; + + extern int TIFFMergeFieldInfo(TIFF *, const TIFFFieldInfo[], uint32_t); -/**************************************************************************** - * O B S O L E T E D I N T E R F A C E S - * - * Don't use this stuff in your applications, it may be removed in the future - * libtiff versions. - ****************************************************************************/ -typedef struct { - ttag_t field_tag; /* field's tag */ - short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */ - short field_writecount; /* write count/TIFF_VARIABLE */ - TIFFDataType field_type; /* type of associated data */ - unsigned short field_bit; /* bit in fieldsset bit vector */ - unsigned char field_oktochange; /* if true, can change while writing */ - unsigned char field_passcount; /* if true, pass dir count on set */ - char *field_name; /* ASCII name */ -} TIFFFieldInfo; - -extern int TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], uint32_t); - #if defined(c_plusplus) || defined(__cplusplus) } #endif diff --git a/libtiff/tiffio.hxx b/libtiff/tiffio.hxx index 19bbffc4..6182449b 100644 --- a/libtiff/tiffio.hxx +++ b/libtiff/tiffio.hxx @@ -2,38 +2,38 @@ * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * - * Permission to use, copy, modify, distribute, and sell this software and + * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF - * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _TIFFIO_HXX_ -#define _TIFFIO_HXX_ +#define _TIFFIO_HXX_ /* * TIFF I/O library definitions which provide C++ streams API. */ -#include <iostream> #include "tiff.h" #include "tiffio.h" +#include <iostream> -extern TIFF* TIFFStreamOpen(const char*, std::ostream *); -extern TIFF* TIFFStreamOpen(const char*, std::istream *); +extern TIFF *TIFFStreamOpen(const char *, std::ostream *); +extern TIFF *TIFFStreamOpen(const char *, std::istream *); #endif /* _TIFFIO_HXX_ */ diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h index 14b7d57b..0a318f62 100644 --- a/libtiff/tiffiop.h +++ b/libtiff/tiffiop.h @@ -23,7 +23,7 @@ */ #ifndef _TIFFIOP_ -#define _TIFFIOP_ +#define _TIFFIOP_ /* * ``Library-private'' definitions. */ @@ -31,19 +31,19 @@ #include "tif_config.h" #ifdef HAVE_FCNTL_H -# include <fcntl.h> +#include <fcntl.h> #endif #ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> +#include <sys/types.h> #endif #include <string.h> #ifdef HAVE_ASSERT_H -# include <assert.h> +#include <assert.h> #else -# define assert(x) +#define assert(x) #endif #include "tiffio.h" @@ -51,18 +51,19 @@ #include "tif_dir.h" #ifndef STRIP_SIZE_DEFAULT -# define STRIP_SIZE_DEFAULT 8192 +#define STRIP_SIZE_DEFAULT 8192 #endif -#define streq(a,b) (strcmp(a,b) == 0) -#define strneq(a,b,n) (strncmp(a,b,n) == 0) +#define streq(a, b) (strcmp(a, b) == 0) +#define strneq(a, b, n) (strncmp(a, b, n) == 0) #ifndef TRUE -#define TRUE 1 -#define FALSE 0 +#define TRUE 1 +#define FALSE 0 #endif -typedef struct client_info { +typedef struct client_info +{ struct client_info *next; void *data; char *name; @@ -72,205 +73,226 @@ typedef struct client_info { * Typedefs for ``method pointers'' used internally. * these are deprecated and provided only for backwards compatibility. */ -typedef unsigned char tidataval_t; /* internal image data value type */ -typedef tidataval_t* tidata_t; /* reference to internal image data */ - -typedef void (*TIFFVoidMethod)(TIFF*); -typedef int (*TIFFBoolMethod)(TIFF*); -typedef int (*TIFFPreMethod)(TIFF*, uint16_t); -typedef int (*TIFFCodeMethod)(TIFF* tif, uint8_t* buf, tmsize_t size, uint16_t sample); -typedef int (*TIFFSeekMethod)(TIFF*, uint32_t); -typedef void (*TIFFPostMethod)(TIFF* tif, uint8_t* buf, tmsize_t size); -typedef uint32_t (*TIFFStripMethod)(TIFF*, uint32_t); -typedef void (*TIFFTileMethod)(TIFF*, uint32_t*, uint32_t*); - -struct tiff { - char* tif_name; /* name of open file */ - int tif_fd; /* open file descriptor */ - int tif_mode; /* open mode (O_*) */ - uint32_t tif_flags; - #define TIFF_FILLORDER 0x00003U /* natural bit fill order for machine */ - #define TIFF_DIRTYHEADER 0x00004U /* header must be written on close */ - #define TIFF_DIRTYDIRECT 0x00008U /* current directory must be written */ - #define TIFF_BUFFERSETUP 0x00010U /* data buffers setup */ - #define TIFF_CODERSETUP 0x00020U /* encoder/decoder setup done */ - #define TIFF_BEENWRITING 0x00040U /* written 1+ scanlines to file */ - #define TIFF_SWAB 0x00080U /* byte swap file information */ - #define TIFF_NOBITREV 0x00100U /* inhibit bit reversal logic */ - #define TIFF_MYBUFFER 0x00200U /* my raw data buffer; free on close */ - #define TIFF_ISTILED 0x00400U /* file is tile, not strip- based */ - #define TIFF_MAPPED 0x00800U /* file is mapped into memory */ - #define TIFF_POSTENCODE 0x01000U /* need call to postencode routine */ - #define TIFF_INSUBIFD 0x02000U /* currently writing a subifd */ - #define TIFF_UPSAMPLED 0x04000U /* library is doing data up-sampling */ - #define TIFF_STRIPCHOP 0x08000U /* enable strip chopping support */ - #define TIFF_HEADERONLY 0x10000U /* read header only, do not process the first directory */ - #define TIFF_NOREADRAW 0x20000U /* skip reading of raw uncompressed image data */ - #define TIFF_INCUSTOMIFD 0x40000U /* currently writing a custom IFD */ - #define TIFF_BIGTIFF 0x80000U /* read/write bigtiff */ - #define TIFF_BUF4WRITE 0x100000U /* rawcc bytes are for writing */ - #define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/ - #define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */ - #define TIFF_BUFFERMMAP 0x800000U /* read buffer (tif_rawdata) points into mmap() memory */ - #define TIFF_DEFERSTRILELOAD 0x1000000U /* defer strip/tile offset/bytecount array loading. */ - #define TIFF_LAZYSTRILELOAD 0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. Only used if TIFF_DEFERSTRILELOAD is set and in read-only mode */ - #define TIFF_CHOPPEDUPARRAYS 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip array */ - uint64_t tif_diroff; /* file offset of current directory */ - uint64_t tif_nextdiroff; /* file offset of following directory */ - uint64_t tif_lastdiroff; /* file offset of last directory written so far */ - uint64_t* tif_dirlistoff; /* list of offsets to already seen directories to prevent IFD looping */ - uint16_t* tif_dirlistdirn; /* list of directory numbers to already seen directories to prevent IFD looping */ - uint16_t tif_dirlistsize; /* number of entries in offset list */ - uint16_t tif_dirnumber; /* number of already seen directories */ - TIFFDirectory tif_dir; /* internal rep of current directory */ - TIFFDirectory tif_customdir; /* custom IFDs are separated from the main ones */ - union { - TIFFHeaderCommon common; - TIFFHeaderClassic classic; - TIFFHeaderBig big; - } tif_header; - uint16_t tif_header_size; /* file's header block and its length */ - uint32_t tif_row; /* current scanline */ - uint16_t tif_curdir; /* current directory (index) */ - uint32_t tif_curstrip; /* current strip for read/write */ - uint64_t tif_curoff; /* current offset for read/write */ - uint64_t tif_lastvalidoff; /* last valid offset allowed for rewrite in place. Used only by TIFFAppendToStrip() */ - uint64_t tif_dataoff; /* current offset for writing dir */ - /* SubIFD support */ - uint16_t tif_nsubifd; /* remaining subifds to write */ - uint64_t tif_subifdoff; /* offset for patching SubIFD link */ - /* tiling support */ - uint32_t tif_col; /* current column (offset by row too) */ - uint32_t tif_curtile; /* current tile for read/write */ - tmsize_t tif_tilesize; /* # of bytes in a tile */ - /* compression scheme hooks */ - int tif_decodestatus; - TIFFBoolMethod tif_fixuptags; /* called in TIFFReadDirectory */ - TIFFBoolMethod tif_setupdecode; /* called once before predecode */ - TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */ - TIFFBoolMethod tif_setupencode; /* called once before preencode */ - int tif_encodestatus; - TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */ - TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */ - TIFFCodeMethod tif_decoderow; /* scanline decoding routine */ - TIFFCodeMethod tif_encoderow; /* scanline encoding routine */ - TIFFCodeMethod tif_decodestrip; /* strip decoding routine */ - TIFFCodeMethod tif_encodestrip; /* strip encoding routine */ - TIFFCodeMethod tif_decodetile; /* tile decoding routine */ - TIFFCodeMethod tif_encodetile; /* tile encoding routine */ - TIFFVoidMethod tif_close; /* cleanup-on-close routine */ - TIFFSeekMethod tif_seek; /* position within a strip routine */ - TIFFVoidMethod tif_cleanup; /* cleanup state routine */ - TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */ - TIFFTileMethod tif_deftilesize; /* calculate/constrain tile size */ - uint8_t* tif_data; /* compression scheme private data */ - /* input/output buffering */ - tmsize_t tif_scanlinesize; /* # of bytes in a scanline */ - tmsize_t tif_scanlineskew; /* scanline skew for reading strips */ - uint8_t* tif_rawdata; /* raw data buffer */ - tmsize_t tif_rawdatasize; /* # of bytes in raw data buffer */ - tmsize_t tif_rawdataoff; /* rawdata offset within strip */ - tmsize_t tif_rawdataloaded;/* amount of data in rawdata */ - uint8_t* tif_rawcp; /* current spot in raw buffer */ - tmsize_t tif_rawcc; /* bytes unread from raw buffer */ - /* memory-mapped file support */ - uint8_t* tif_base; /* base of mapped file */ - tmsize_t tif_size; /* size of mapped file region (bytes, thus tmsize_t) */ - TIFFMapFileProc tif_mapproc; /* map file method */ - TIFFUnmapFileProc tif_unmapproc; /* unmap file method */ - /* input/output callback methods */ - thandle_t tif_clientdata; /* callback parameter */ - TIFFReadWriteProc tif_readproc; /* read method */ - TIFFReadWriteProc tif_writeproc; /* write method */ - TIFFSeekProc tif_seekproc; /* lseek method */ - TIFFCloseProc tif_closeproc; /* close method */ - TIFFSizeProc tif_sizeproc; /* filesize method */ - /* post-decoding support */ - TIFFPostMethod tif_postdecode; /* post decoding routine */ - /* tag support */ - TIFFField** tif_fields; /* sorted table of registered tags */ - size_t tif_nfields; /* # entries in registered tag table */ - const TIFFField* tif_foundfield; /* cached pointer to already found tag */ - TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */ - TIFFClientInfoLink* tif_clientinfo; /* extra client information. */ - /* Backward compatibility stuff. We need these two fields for - * setting up an old tag extension scheme. */ - TIFFFieldArray* tif_fieldscompat; - size_t tif_nfieldscompat; - /* Error handler support */ - TIFFErrorHandlerExtR tif_errorhandler; - void* tif_errorhandler_user_data; - TIFFErrorHandlerExtR tif_warnhandler; - void* tif_warnhandler_user_data; - tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */ +typedef unsigned char tidataval_t; /* internal image data value type */ +typedef tidataval_t *tidata_t; /* reference to internal image data */ + +typedef void (*TIFFVoidMethod)(TIFF *); +typedef int (*TIFFBoolMethod)(TIFF *); +typedef int (*TIFFPreMethod)(TIFF *, uint16_t); +typedef int (*TIFFCodeMethod)(TIFF *tif, uint8_t *buf, tmsize_t size, + uint16_t sample); +typedef int (*TIFFSeekMethod)(TIFF *, uint32_t); +typedef void (*TIFFPostMethod)(TIFF *tif, uint8_t *buf, tmsize_t size); +typedef uint32_t (*TIFFStripMethod)(TIFF *, uint32_t); +typedef void (*TIFFTileMethod)(TIFF *, uint32_t *, uint32_t *); + +struct tiff +{ + char *tif_name; /* name of open file */ + int tif_fd; /* open file descriptor */ + int tif_mode; /* open mode (O_*) */ + uint32_t tif_flags; +#define TIFF_FILLORDER 0x00003U /* natural bit fill order for machine */ +#define TIFF_DIRTYHEADER 0x00004U /* header must be written on close */ +#define TIFF_DIRTYDIRECT 0x00008U /* current directory must be written */ +#define TIFF_BUFFERSETUP 0x00010U /* data buffers setup */ +#define TIFF_CODERSETUP 0x00020U /* encoder/decoder setup done */ +#define TIFF_BEENWRITING 0x00040U /* written 1+ scanlines to file */ +#define TIFF_SWAB 0x00080U /* byte swap file information */ +#define TIFF_NOBITREV 0x00100U /* inhibit bit reversal logic */ +#define TIFF_MYBUFFER 0x00200U /* my raw data buffer; free on close */ +#define TIFF_ISTILED 0x00400U /* file is tile, not strip- based */ +#define TIFF_MAPPED 0x00800U /* file is mapped into memory */ +#define TIFF_POSTENCODE 0x01000U /* need call to postencode routine */ +#define TIFF_INSUBIFD 0x02000U /* currently writing a subifd */ +#define TIFF_UPSAMPLED 0x04000U /* library is doing data up-sampling */ +#define TIFF_STRIPCHOP 0x08000U /* enable strip chopping support */ +#define TIFF_HEADERONLY \ + 0x10000U /* read header only, do not process the first directory */ +#define TIFF_NOREADRAW \ + 0x20000U /* skip reading of raw uncompressed image data */ +#define TIFF_INCUSTOMIFD 0x40000U /* currently writing a custom IFD */ +#define TIFF_BIGTIFF 0x80000U /* read/write bigtiff */ +#define TIFF_BUF4WRITE 0x100000U /* rawcc bytes are for writing */ +#define TIFF_DIRTYSTRIP 0x200000U /* stripoffsets/stripbytecount dirty*/ +#define TIFF_PERSAMPLE 0x400000U /* get/set per sample tags as arrays */ +#define TIFF_BUFFERMMAP \ + 0x800000U /* read buffer (tif_rawdata) points into mmap() memory */ +#define TIFF_DEFERSTRILELOAD \ + 0x1000000U /* defer strip/tile offset/bytecount array loading. */ +#define TIFF_LAZYSTRILELOAD \ + 0x2000000U /* lazy/ondemand loading of strip/tile offset/bytecount values. \ + Only used if TIFF_DEFERSTRILELOAD is set and in read-only \ + mode */ +#define TIFF_CHOPPEDUPARRAYS \ + 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip \ + array */ + uint64_t tif_diroff; /* file offset of current directory */ + uint64_t tif_nextdiroff; /* file offset of following directory */ + uint64_t tif_lastdiroff; /* file offset of last directory written so far */ + uint64_t *tif_dirlistoff; /* list of offsets to already seen directories to + prevent IFD looping */ + uint16_t *tif_dirlistdirn; /* list of directory numbers to already seen + directories to prevent IFD looping */ + uint16_t tif_dirlistsize; /* number of entries in offset list */ + uint16_t tif_dirnumber; /* number of already seen directories */ + TIFFDirectory tif_dir; /* internal rep of current directory */ + TIFFDirectory + tif_customdir; /* custom IFDs are separated from the main ones */ + union + { + TIFFHeaderCommon common; + TIFFHeaderClassic classic; + TIFFHeaderBig big; + } tif_header; + uint16_t tif_header_size; /* file's header block and its length */ + uint32_t tif_row; /* current scanline */ + uint16_t tif_curdir; /* current directory (index) */ + uint32_t tif_curstrip; /* current strip for read/write */ + uint64_t tif_curoff; /* current offset for read/write */ + uint64_t tif_lastvalidoff; /* last valid offset allowed for rewrite in + place. Used only by TIFFAppendToStrip() */ + uint64_t tif_dataoff; /* current offset for writing dir */ + /* SubIFD support */ + uint16_t tif_nsubifd; /* remaining subifds to write */ + uint64_t tif_subifdoff; /* offset for patching SubIFD link */ + /* tiling support */ + uint32_t tif_col; /* current column (offset by row too) */ + uint32_t tif_curtile; /* current tile for read/write */ + tmsize_t tif_tilesize; /* # of bytes in a tile */ + /* compression scheme hooks */ + int tif_decodestatus; + TIFFBoolMethod tif_fixuptags; /* called in TIFFReadDirectory */ + TIFFBoolMethod tif_setupdecode; /* called once before predecode */ + TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */ + TIFFBoolMethod tif_setupencode; /* called once before preencode */ + int tif_encodestatus; + TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */ + TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */ + TIFFCodeMethod tif_decoderow; /* scanline decoding routine */ + TIFFCodeMethod tif_encoderow; /* scanline encoding routine */ + TIFFCodeMethod tif_decodestrip; /* strip decoding routine */ + TIFFCodeMethod tif_encodestrip; /* strip encoding routine */ + TIFFCodeMethod tif_decodetile; /* tile decoding routine */ + TIFFCodeMethod tif_encodetile; /* tile encoding routine */ + TIFFVoidMethod tif_close; /* cleanup-on-close routine */ + TIFFSeekMethod tif_seek; /* position within a strip routine */ + TIFFVoidMethod tif_cleanup; /* cleanup state routine */ + TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */ + TIFFTileMethod tif_deftilesize; /* calculate/constrain tile size */ + uint8_t *tif_data; /* compression scheme private data */ + /* input/output buffering */ + tmsize_t tif_scanlinesize; /* # of bytes in a scanline */ + tmsize_t tif_scanlineskew; /* scanline skew for reading strips */ + uint8_t *tif_rawdata; /* raw data buffer */ + tmsize_t tif_rawdatasize; /* # of bytes in raw data buffer */ + tmsize_t tif_rawdataoff; /* rawdata offset within strip */ + tmsize_t tif_rawdataloaded; /* amount of data in rawdata */ + uint8_t *tif_rawcp; /* current spot in raw buffer */ + tmsize_t tif_rawcc; /* bytes unread from raw buffer */ + /* memory-mapped file support */ + uint8_t *tif_base; /* base of mapped file */ + tmsize_t tif_size; /* size of mapped file region (bytes, thus tmsize_t) */ + TIFFMapFileProc tif_mapproc; /* map file method */ + TIFFUnmapFileProc tif_unmapproc; /* unmap file method */ + /* input/output callback methods */ + thandle_t tif_clientdata; /* callback parameter */ + TIFFReadWriteProc tif_readproc; /* read method */ + TIFFReadWriteProc tif_writeproc; /* write method */ + TIFFSeekProc tif_seekproc; /* lseek method */ + TIFFCloseProc tif_closeproc; /* close method */ + TIFFSizeProc tif_sizeproc; /* filesize method */ + /* post-decoding support */ + TIFFPostMethod tif_postdecode; /* post decoding routine */ + /* tag support */ + TIFFField **tif_fields; /* sorted table of registered tags */ + size_t tif_nfields; /* # entries in registered tag table */ + const TIFFField *tif_foundfield; /* cached pointer to already found tag */ + TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */ + TIFFClientInfoLink *tif_clientinfo; /* extra client information. */ + /* Backward compatibility stuff. We need these two fields for + * setting up an old tag extension scheme. */ + TIFFFieldArray *tif_fieldscompat; + size_t tif_nfieldscompat; + /* Error handler support */ + TIFFErrorHandlerExtR tif_errorhandler; + void *tif_errorhandler_user_data; + TIFFErrorHandlerExtR tif_warnhandler; + void *tif_warnhandler_user_data; + tmsize_t tif_max_single_mem_alloc; /* in bytes. 0 for unlimited */ }; struct TIFFOpenOptions { TIFFErrorHandlerExtR errorhandler; /* may be NULL */ - void* errorhandler_user_data; /* may be NULL */ - TIFFErrorHandlerExtR warnhandler; /* may be NULL */ - void* warnhandler_user_data; /* may be NULL */ - tmsize_t max_single_mem_alloc; /* in bytes. 0 for unlimited */ + void *errorhandler_user_data; /* may be NULL */ + TIFFErrorHandlerExtR warnhandler; /* may be NULL */ + void *warnhandler_user_data; /* may be NULL */ + tmsize_t max_single_mem_alloc; /* in bytes. 0 for unlimited */ }; -#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ +#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */ #define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0) #define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0) #define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0) #define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0) -#define TIFFReadFile(tif, buf, size) \ - ((*(tif)->tif_readproc)((tif)->tif_clientdata,(buf),(size))) -#define TIFFWriteFile(tif, buf, size) \ - ((*(tif)->tif_writeproc)((tif)->tif_clientdata,(buf),(size))) -#define TIFFSeekFile(tif, off, whence) \ - ((*(tif)->tif_seekproc)((tif)->tif_clientdata,(off),(whence))) -#define TIFFCloseFile(tif) \ - ((*(tif)->tif_closeproc)((tif)->tif_clientdata)) -#define TIFFGetFileSize(tif) \ - ((*(tif)->tif_sizeproc)((tif)->tif_clientdata)) -#define TIFFMapFileContents(tif, paddr, psize) \ - ((*(tif)->tif_mapproc)((tif)->tif_clientdata,(paddr),(psize))) -#define TIFFUnmapFileContents(tif, addr, size) \ - ((*(tif)->tif_unmapproc)((tif)->tif_clientdata,(addr),(size))) +#define TIFFReadFile(tif, buf, size) \ + ((*(tif)->tif_readproc)((tif)->tif_clientdata, (buf), (size))) +#define TIFFWriteFile(tif, buf, size) \ + ((*(tif)->tif_writeproc)((tif)->tif_clientdata, (buf), (size))) +#define TIFFSeekFile(tif, off, whence) \ + ((*(tif)->tif_seekproc)((tif)->tif_clientdata, (off), (whence))) +#define TIFFCloseFile(tif) ((*(tif)->tif_closeproc)((tif)->tif_clientdata)) +#define TIFFGetFileSize(tif) ((*(tif)->tif_sizeproc)((tif)->tif_clientdata)) +#define TIFFMapFileContents(tif, paddr, psize) \ + ((*(tif)->tif_mapproc)((tif)->tif_clientdata, (paddr), (psize))) +#define TIFFUnmapFileContents(tif, addr, size) \ + ((*(tif)->tif_unmapproc)((tif)->tif_clientdata, (addr), (size))) /* * Default Read/Seek/Write definitions. */ #ifndef ReadOK -#define ReadOK(tif, buf, size) \ - (TIFFReadFile((tif),(buf),(size))==(size)) +#define ReadOK(tif, buf, size) (TIFFReadFile((tif), (buf), (size)) == (size)) #endif #ifndef SeekOK #define SeekOK(tif, off) _TIFFSeekOK(tif, off) #endif #ifndef WriteOK -#define WriteOK(tif, buf, size) \ - (TIFFWriteFile((tif),(buf),(size))==(size)) +#define WriteOK(tif, buf, size) (TIFFWriteFile((tif), (buf), (size)) == (size)) #endif /* NB: the uint32_t casts are to silence certain ANSI-C compilers */ -#define TIFFhowmany_32(x, y) (((uint32_t)x < (0xffffffff - (uint32_t)(y-1))) ? \ - ((((uint32_t)(x))+(((uint32_t)(y))-1))/((uint32_t)(y))) : \ - 0U) +#define TIFFhowmany_32(x, y) \ + (((uint32_t)x < (0xffffffff - (uint32_t)(y - 1))) \ + ? ((((uint32_t)(x)) + (((uint32_t)(y)) - 1)) / ((uint32_t)(y))) \ + : 0U) /* Variant of TIFFhowmany_32() that doesn't return 0 if x close to MAXUINT. */ /* Caution: TIFFhowmany_32_maxuint_compat(x,y)*y might overflow */ -#define TIFFhowmany_32_maxuint_compat(x, y) \ - (((uint32_t)(x) / (uint32_t)(y)) + ((((uint32_t)(x) % (uint32_t)(y)) != 0) ? 1 : 0)) -#define TIFFhowmany8_32(x) (((x)&0x07)?((uint32_t)(x)>>3)+1:(uint32_t)(x)>>3) -#define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y)) -#define TIFFhowmany_64(x, y) ((((uint64_t)(x))+(((uint64_t)(y))-1))/((uint64_t)(y))) -#define TIFFhowmany8_64(x) (((x)&0x07)?((uint64_t)(x)>>3)+1:(uint64_t)(x)>>3) -#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y)) - -/* Safe multiply which returns zero if there is an *unsigned* integer overflow. This macro is not safe for *signed* integer types */ -#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0) - -#define TIFFmax(A,B) ((A)>(B)?(A):(B)) -#define TIFFmin(A,B) ((A)<(B)?(A):(B)) - -#define TIFFArrayCount(a) (sizeof (a) / sizeof ((a)[0])) +#define TIFFhowmany_32_maxuint_compat(x, y) \ + (((uint32_t)(x) / (uint32_t)(y)) + \ + ((((uint32_t)(x) % (uint32_t)(y)) != 0) ? 1 : 0)) +#define TIFFhowmany8_32(x) \ + (((x)&0x07) ? ((uint32_t)(x) >> 3) + 1 : (uint32_t)(x) >> 3) +#define TIFFroundup_32(x, y) (TIFFhowmany_32(x, y) * (y)) +#define TIFFhowmany_64(x, y) \ + ((((uint64_t)(x)) + (((uint64_t)(y)) - 1)) / ((uint64_t)(y))) +#define TIFFhowmany8_64(x) \ + (((x)&0x07) ? ((uint64_t)(x) >> 3) + 1 : (uint64_t)(x) >> 3) +#define TIFFroundup_64(x, y) (TIFFhowmany_64(x, y) * (y)) + +/* Safe multiply which returns zero if there is an *unsigned* integer overflow. + * This macro is not safe for *signed* integer types */ +#define TIFFSafeMultiply(t, v, m) \ + ((((t)(m) != (t)0) && (((t)(((v) * (m)) / (m))) == (t)(v))) \ + ? (t)((v) * (m)) \ + : (t)0) + +#define TIFFmax(A, B) ((A) > (B) ? (A) : (B)) +#define TIFFmin(A, B) ((A) < (B) ? (A) : (B)) + +#define TIFFArrayCount(a) (sizeof(a) / sizeof((a)[0])) /* Support for large files. @@ -291,28 +313,31 @@ struct TIFFOpenOptions must be available on the target computer in order for the program to run. */ #if defined(HAVE_FSEEKO) -# define fseek(stream,offset,whence) fseeko(stream,offset,whence) -# define ftell(stream,offset,whence) ftello(stream,offset,whence) +#define fseek(stream, offset, whence) fseeko(stream, offset, whence) +#define ftell(stream, offset, whence) ftello(stream, offset, whence) #endif #endif -#if defined(__WIN32__) && \ - !(defined(_MSC_VER) && _MSC_VER < 1400) && \ - !(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800) +#if defined(__WIN32__) && !(defined(_MSC_VER) && _MSC_VER < 1400) && \ + !(defined(__MSVCRT_VERSION__) && __MSVCRT_VERSION__ < 0x800) typedef unsigned int TIFFIOSize_t; -#define _TIFF_lseek_f(fildes,offset,whence) _lseeki64(fildes,/* __int64 */ offset,whence) +#define _TIFF_lseek_f(fildes, offset, whence) \ + _lseeki64(fildes, /* __int64 */ offset, whence) /* #define _TIFF_tell_f(fildes) /\* __int64 *\/ _telli64(fildes) */ -#define _TIFF_fseek_f(stream,offset,whence) _fseeki64(stream,/* __int64 */ offset,whence) -#define _TIFF_fstat_f(fildes,stat_buff) _fstati64(fildes,/* struct _stati64 */ stat_buff) +#define _TIFF_fseek_f(stream, offset, whence) \ + _fseeki64(stream, /* __int64 */ offset, whence) +#define _TIFF_fstat_f(fildes, stat_buff) \ + _fstati64(fildes, /* struct _stati64 */ stat_buff) /* #define _TIFF_ftell_f(stream) /\* __int64 *\/ _ftelli64(stream) */ -/* #define _TIFF_stat_f(path,stat_buff) _stati64(path,/\* struct _stati64 *\/ stat_buff) */ +/* #define _TIFF_stat_f(path,stat_buff) _stati64(path,/\* struct _stati64 *\/ + * stat_buff) */ #define _TIFF_stat_s struct _stati64 #define _TIFF_off_t __int64 #else typedef size_t TIFFIOSize_t; -#define _TIFF_lseek_f(fildes,offset,whence) lseek(fildes,offset,whence) +#define _TIFF_lseek_f(fildes, offset, whence) lseek(fildes, offset, whence) /* #define _TIFF_tell_f(fildes) (_TIFF_lseek_f(fildes,0,SEEK_CUR)) */ -#define _TIFF_fseek_f(stream,offset,whence) fseek(stream,offset,whence) -#define _TIFF_fstat_f(fildes,stat_buff) fstat(fildes,stat_buff) +#define _TIFF_fseek_f(stream, offset, whence) fseek(stream, offset, whence) +#define _TIFF_fstat_f(fildes, stat_buff) fstat(fildes, stat_buff) /* #define _TIFF_ftell_f(stream) ftell(stream) */ /* #define _TIFF_stat_f(path,stat_buff) stat(path,stat_buff) */ #define _TIFF_stat_s struct stat @@ -321,7 +346,8 @@ typedef size_t TIFFIOSize_t; #if defined(__has_attribute) && defined(__clang__) #if __has_attribute(no_sanitize) -#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow"))) +#define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW \ + __attribute__((no_sanitize("unsigned-integer-overflow"))) #else #define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW #endif @@ -329,136 +355,151 @@ typedef size_t TIFFIOSize_t; #define TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW #endif - #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -extern int _TIFFgetMode(TIFFOpenOptions* opts, thandle_t clientdata, const char* mode, const char* module); -extern int _TIFFNoRowEncode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s); -extern int _TIFFNoStripEncode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s); -extern int _TIFFNoTileEncode(TIFF*, uint8_t* pp, tmsize_t cc, uint16_t s); -extern int _TIFFNoRowDecode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s); -extern int _TIFFNoStripDecode(TIFF* tif, uint8_t* pp, tmsize_t cc, uint16_t s); -extern int _TIFFNoTileDecode(TIFF*, uint8_t* pp, tmsize_t cc, uint16_t s); -extern void _TIFFNoPostDecode(TIFF* tif, uint8_t* buf, tmsize_t cc); -extern int _TIFFNoPreCode(TIFF* tif, uint16_t s); -extern int _TIFFNoSeek(TIFF* tif, uint32_t off); -extern void _TIFFSwab16BitData(TIFF* tif, uint8_t* buf, tmsize_t cc); -extern void _TIFFSwab24BitData(TIFF* tif, uint8_t* buf, tmsize_t cc); -extern void _TIFFSwab32BitData(TIFF* tif, uint8_t* buf, tmsize_t cc); -extern void _TIFFSwab64BitData(TIFF* tif, uint8_t* buf, tmsize_t cc); -extern int TIFFFlushData1(TIFF* tif); -extern int TIFFDefaultDirectory(TIFF* tif); -extern void _TIFFSetDefaultCompressionState(TIFF* tif); -extern int _TIFFRewriteField(TIFF *, uint16_t, TIFFDataType, tmsize_t, void *); -extern int TIFFSetCompressionScheme(TIFF* tif, int scheme); -extern int TIFFSetDefaultCompressionState(TIFF* tif); -extern uint32_t _TIFFDefaultStripSize(TIFF* tif, uint32_t s); -extern void _TIFFDefaultTileSize(TIFF* tif, uint32_t* tw, uint32_t* th); - -extern void _TIFFsetByteArray(void**, const void*, uint32_t); -extern void _TIFFsetByteArrayExt(TIFF*, void**, const void*, uint32_t); -extern void _TIFFsetShortArray(uint16_t**, const uint16_t*, uint32_t); -extern void _TIFFsetShortArrayExt(TIFF*, uint16_t**, const uint16_t*, uint32_t); -extern void _TIFFsetLongArray(uint32_t**, const uint32_t*, uint32_t); -extern void _TIFFsetLongArrayExt(TIFF*, uint32_t**, const uint32_t*, uint32_t); -extern void _TIFFsetFloatArray(float**, const float*, uint32_t); -extern void _TIFFsetFloatArrayExt(TIFF*, float**, const float*, uint32_t); -extern void _TIFFsetDoubleArray(double**, const double*, uint32_t); -extern void _TIFFsetDoubleArrayExt(TIFF*, double**, const double*, uint32_t); - -extern void _TIFFprintAscii(FILE*, const char*); -extern void _TIFFprintAsciiTag(FILE*, const char*, const char*); - -extern TIFFErrorHandler _TIFFwarningHandler; -extern TIFFErrorHandler _TIFFerrorHandler; -extern TIFFErrorHandlerExt _TIFFwarningHandlerExt; -extern TIFFErrorHandlerExt _TIFFerrorHandlerExt; -void _TIFFErrorEarly(TIFFOpenOptions* opts, thandle_t clientdata, const char* module, const char* fmt, ...) TIFF_ATTRIBUTE((__format__ (__printf__,4,5))); - -extern uint32_t _TIFFMultiply32(TIFF*, uint32_t, uint32_t, const char*); -extern uint64_t _TIFFMultiply64(TIFF*, uint64_t, uint64_t, const char*); -extern tmsize_t _TIFFMultiplySSize(TIFF*, tmsize_t, tmsize_t, const char*); -extern tmsize_t _TIFFCastUInt64ToSSize(TIFF*, uint64_t, const char*); -extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*); -extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*); - -extern double _TIFFUInt64ToDouble(uint64_t); -extern float _TIFFUInt64ToFloat(uint64_t); - -extern float _TIFFClampDoubleToFloat(double); -extern uint32_t _TIFFClampDoubleToUInt32(double); - -extern tmsize_t -_TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32_t strip, - void **buf, tmsize_t bufsizetoalloc, - tmsize_t size_to_read); -extern tmsize_t -_TIFFReadEncodedTileAndAllocBuffer(TIFF* tif, uint32_t tile, - void **buf, tmsize_t bufsizetoalloc, - tmsize_t size_to_read); -extern tmsize_t -_TIFFReadTileAndAllocBuffer(TIFF* tif, - void **buf, tmsize_t bufsizetoalloc, - uint32_t x, uint32_t y, uint32_t z, uint16_t s); -extern int _TIFFSeekOK(TIFF* tif, toff_t off); - -extern int TIFFInitDumpMode(TIFF*, int); + extern int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, + const char *mode, const char *module); + extern int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, + uint16_t s); + extern int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, + uint16_t s); + extern int _TIFFNoTileEncode(TIFF *, uint8_t *pp, tmsize_t cc, uint16_t s); + extern int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, + uint16_t s); + extern int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, + uint16_t s); + extern int _TIFFNoTileDecode(TIFF *, uint8_t *pp, tmsize_t cc, uint16_t s); + extern void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc); + extern int _TIFFNoPreCode(TIFF *tif, uint16_t s); + extern int _TIFFNoSeek(TIFF *tif, uint32_t off); + extern void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); + extern void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); + extern void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); + extern void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc); + extern int TIFFFlushData1(TIFF *tif); + extern int TIFFDefaultDirectory(TIFF *tif); + extern void _TIFFSetDefaultCompressionState(TIFF *tif); + extern int _TIFFRewriteField(TIFF *, uint16_t, TIFFDataType, tmsize_t, + void *); + extern int TIFFSetCompressionScheme(TIFF *tif, int scheme); + extern int TIFFSetDefaultCompressionState(TIFF *tif); + extern uint32_t _TIFFDefaultStripSize(TIFF *tif, uint32_t s); + extern void _TIFFDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th); + + extern void _TIFFsetByteArray(void **, const void *, uint32_t); + extern void _TIFFsetByteArrayExt(TIFF *, void **, const void *, uint32_t); + extern void _TIFFsetShortArray(uint16_t **, const uint16_t *, uint32_t); + extern void _TIFFsetShortArrayExt(TIFF *, uint16_t **, const uint16_t *, + uint32_t); + extern void _TIFFsetLongArray(uint32_t **, const uint32_t *, uint32_t); + extern void _TIFFsetLongArrayExt(TIFF *, uint32_t **, const uint32_t *, + uint32_t); + extern void _TIFFsetFloatArray(float **, const float *, uint32_t); + extern void _TIFFsetFloatArrayExt(TIFF *, float **, const float *, + uint32_t); + extern void _TIFFsetDoubleArray(double **, const double *, uint32_t); + extern void _TIFFsetDoubleArrayExt(TIFF *, double **, const double *, + uint32_t); + + extern void _TIFFprintAscii(FILE *, const char *); + extern void _TIFFprintAsciiTag(FILE *, const char *, const char *); + + extern TIFFErrorHandler _TIFFwarningHandler; + extern TIFFErrorHandler _TIFFerrorHandler; + extern TIFFErrorHandlerExt _TIFFwarningHandlerExt; + extern TIFFErrorHandlerExt _TIFFerrorHandlerExt; + void _TIFFErrorEarly(TIFFOpenOptions *opts, thandle_t clientdata, + const char *module, const char *fmt, ...) + TIFF_ATTRIBUTE((__format__(__printf__, 4, 5))); + + extern uint32_t _TIFFMultiply32(TIFF *, uint32_t, uint32_t, const char *); + extern uint64_t _TIFFMultiply64(TIFF *, uint64_t, uint64_t, const char *); + extern tmsize_t _TIFFMultiplySSize(TIFF *, tmsize_t, tmsize_t, + const char *); + extern tmsize_t _TIFFCastUInt64ToSSize(TIFF *, uint64_t, const char *); + extern void *_TIFFCheckMalloc(TIFF *, tmsize_t, tmsize_t, const char *); + extern void *_TIFFCheckRealloc(TIFF *, void *, tmsize_t, tmsize_t, + const char *); + + extern double _TIFFUInt64ToDouble(uint64_t); + extern float _TIFFUInt64ToFloat(uint64_t); + + extern float _TIFFClampDoubleToFloat(double); + extern uint32_t _TIFFClampDoubleToUInt32(double); + + extern tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, + uint32_t strip, + void **buf, + tmsize_t bufsizetoalloc, + tmsize_t size_to_read); + extern tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile, + void **buf, + tmsize_t bufsizetoalloc, + tmsize_t size_to_read); + extern tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf, + tmsize_t bufsizetoalloc, + uint32_t x, uint32_t y, + uint32_t z, uint16_t s); + extern int _TIFFSeekOK(TIFF *tif, toff_t off); + + extern int TIFFInitDumpMode(TIFF *, int); #ifdef PACKBITS_SUPPORT -extern int TIFFInitPackBits(TIFF*, int); + extern int TIFFInitPackBits(TIFF *, int); #endif #ifdef CCITT_SUPPORT -extern int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int); -extern int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int); + extern int TIFFInitCCITTRLE(TIFF *, int), TIFFInitCCITTRLEW(TIFF *, int); + extern int TIFFInitCCITTFax3(TIFF *, int), TIFFInitCCITTFax4(TIFF *, int); #endif #ifdef THUNDER_SUPPORT -extern int TIFFInitThunderScan(TIFF*, int); + extern int TIFFInitThunderScan(TIFF *, int); #endif #ifdef NEXT_SUPPORT -extern int TIFFInitNeXT(TIFF*, int); + extern int TIFFInitNeXT(TIFF *, int); #endif #ifdef LZW_SUPPORT -extern int TIFFInitLZW(TIFF*, int); + extern int TIFFInitLZW(TIFF *, int); #endif #ifdef OJPEG_SUPPORT -extern int TIFFInitOJPEG(TIFF*, int); + extern int TIFFInitOJPEG(TIFF *, int); #endif #ifdef JPEG_SUPPORT -extern int TIFFInitJPEG(TIFF*, int); -extern int TIFFJPEGIsFullStripRequired(TIFF*); + extern int TIFFInitJPEG(TIFF *, int); + extern int TIFFJPEGIsFullStripRequired(TIFF *); #endif #ifdef JBIG_SUPPORT -extern int TIFFInitJBIG(TIFF*, int); + extern int TIFFInitJBIG(TIFF *, int); #endif #ifdef ZIP_SUPPORT -extern int TIFFInitZIP(TIFF*, int); + extern int TIFFInitZIP(TIFF *, int); #endif #ifdef PIXARLOG_SUPPORT -extern int TIFFInitPixarLog(TIFF*, int); + extern int TIFFInitPixarLog(TIFF *, int); #endif #ifdef LOGLUV_SUPPORT -extern int TIFFInitSGILog(TIFF*, int); + extern int TIFFInitSGILog(TIFF *, int); #endif #ifdef LERC_SUPPORT -extern int TIFFInitLERC(TIFF* tif, int); + extern int TIFFInitLERC(TIFF *tif, int); #endif #ifdef LZMA_SUPPORT -extern int TIFFInitLZMA(TIFF*, int); + extern int TIFFInitLZMA(TIFF *, int); #endif #ifdef ZSTD_SUPPORT -extern int TIFFInitZSTD(TIFF*, int); + extern int TIFFInitZSTD(TIFF *, int); #endif #ifdef WEBP_SUPPORT -extern int TIFFInitWebP(TIFF*, int); + extern int TIFFInitWebP(TIFF *, int); #endif -extern const TIFFCodec _TIFFBuiltinCODECS[]; -extern void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *, uint32_t l, int32_t a, int32_t b, - float *, float *, float *); - -extern void* _TIFFmallocExt(TIFF* tif, tmsize_t s); -extern void* _TIFFcallocExt(TIFF* tif, tmsize_t nmemb, tmsize_t siz); -extern void* _TIFFreallocExt(TIFF* tif, void* p, tmsize_t s); -extern void _TIFFfreeExt(TIFF* tif, void* p); + extern const TIFFCodec _TIFFBuiltinCODECS[]; + extern void TIFFCIELab16ToXYZ(TIFFCIELabToRGB *, uint32_t l, int32_t a, + int32_t b, float *, float *, float *); + + extern void *_TIFFmallocExt(TIFF *tif, tmsize_t s); + extern void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz); + extern void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s); + extern void _TIFFfreeExt(TIFF *tif, void *p); #if defined(__cplusplus) } diff --git a/libtiff/tiffvers.h b/libtiff/tiffvers.h index 084f335d..cbeec2c9 100644 --- a/libtiff/tiffvers.h +++ b/libtiff/tiffvers.h @@ -1,4 +1,6 @@ -#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.4.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc." +#define TIFFLIB_VERSION_STR \ + "LIBTIFF, Version 4.4.0\nCopyright (c) 1988-1996 Sam Leffler\nCopyright " \ + "(c) 1991-1996 Silicon Graphics, Inc." /* * This define can be used in code that requires * compilation-related definitions specific to a diff --git a/libtiff/uvcode.h b/libtiff/uvcode.h index f1585b4d..fc877292 100644 --- a/libtiff/uvcode.h +++ b/libtiff/uvcode.h @@ -1,173 +1,93 @@ /* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */ -#define UV_SQSIZ (float)0.003500 -#define UV_NDIVS 16289 -#define UV_VSTART (float)0.016940 -#define UV_NVS 163 -static const struct { - float ustart; - short nus, ncum; -} uv_row[UV_NVS] = { - { (float)0.247663, 4, 0 }, - { (float)0.243779, 6, 4 }, - { (float)0.241684, 7, 10 }, - { (float)0.237874, 9, 17 }, - { (float)0.235906, 10, 26 }, - { (float)0.232153, 12, 36 }, - { (float)0.228352, 14, 48 }, - { (float)0.226259, 15, 62 }, - { (float)0.222371, 17, 77 }, - { (float)0.220410, 18, 94 }, - { (float)0.214710, 21, 112 }, - { (float)0.212714, 22, 133 }, - { (float)0.210721, 23, 155 }, - { (float)0.204976, 26, 178 }, - { (float)0.202986, 27, 204 }, - { (float)0.199245, 29, 231 }, - { (float)0.195525, 31, 260 }, - { (float)0.193560, 32, 291 }, - { (float)0.189878, 34, 323 }, - { (float)0.186216, 36, 357 }, - { (float)0.186216, 36, 393 }, - { (float)0.182592, 38, 429 }, - { (float)0.179003, 40, 467 }, - { (float)0.175466, 42, 507 }, - { (float)0.172001, 44, 549 }, - { (float)0.172001, 44, 593 }, - { (float)0.168612, 46, 637 }, - { (float)0.168612, 46, 683 }, - { (float)0.163575, 49, 729 }, - { (float)0.158642, 52, 778 }, - { (float)0.158642, 52, 830 }, - { (float)0.158642, 52, 882 }, - { (float)0.153815, 55, 934 }, - { (float)0.153815, 55, 989 }, - { (float)0.149097, 58, 1044 }, - { (float)0.149097, 58, 1102 }, - { (float)0.142746, 62, 1160 }, - { (float)0.142746, 62, 1222 }, - { (float)0.142746, 62, 1284 }, - { (float)0.138270, 65, 1346 }, - { (float)0.138270, 65, 1411 }, - { (float)0.138270, 65, 1476 }, - { (float)0.132166, 69, 1541 }, - { (float)0.132166, 69, 1610 }, - { (float)0.126204, 73, 1679 }, - { (float)0.126204, 73, 1752 }, - { (float)0.126204, 73, 1825 }, - { (float)0.120381, 77, 1898 }, - { (float)0.120381, 77, 1975 }, - { (float)0.120381, 77, 2052 }, - { (float)0.120381, 77, 2129 }, - { (float)0.112962, 82, 2206 }, - { (float)0.112962, 82, 2288 }, - { (float)0.112962, 82, 2370 }, - { (float)0.107450, 86, 2452 }, - { (float)0.107450, 86, 2538 }, - { (float)0.107450, 86, 2624 }, - { (float)0.107450, 86, 2710 }, - { (float)0.100343, 91, 2796 }, - { (float)0.100343, 91, 2887 }, - { (float)0.100343, 91, 2978 }, - { (float)0.095126, 95, 3069 }, - { (float)0.095126, 95, 3164 }, - { (float)0.095126, 95, 3259 }, - { (float)0.095126, 95, 3354 }, - { (float)0.088276, 100, 3449 }, - { (float)0.088276, 100, 3549 }, - { (float)0.088276, 100, 3649 }, - { (float)0.088276, 100, 3749 }, - { (float)0.081523, 105, 3849 }, - { (float)0.081523, 105, 3954 }, - { (float)0.081523, 105, 4059 }, - { (float)0.081523, 105, 4164 }, - { (float)0.074861, 110, 4269 }, - { (float)0.074861, 110, 4379 }, - { (float)0.074861, 110, 4489 }, - { (float)0.074861, 110, 4599 }, - { (float)0.068290, 115, 4709 }, - { (float)0.068290, 115, 4824 }, - { (float)0.068290, 115, 4939 }, - { (float)0.068290, 115, 5054 }, - { (float)0.063573, 119, 5169 }, - { (float)0.063573, 119, 5288 }, - { (float)0.063573, 119, 5407 }, - { (float)0.063573, 119, 5526 }, - { (float)0.057219, 124, 5645 }, - { (float)0.057219, 124, 5769 }, - { (float)0.057219, 124, 5893 }, - { (float)0.057219, 124, 6017 }, - { (float)0.050985, 129, 6141 }, - { (float)0.050985, 129, 6270 }, - { (float)0.050985, 129, 6399 }, - { (float)0.050985, 129, 6528 }, - { (float)0.050985, 129, 6657 }, - { (float)0.044859, 134, 6786 }, - { (float)0.044859, 134, 6920 }, - { (float)0.044859, 134, 7054 }, - { (float)0.044859, 134, 7188 }, - { (float)0.040571, 138, 7322 }, - { (float)0.040571, 138, 7460 }, - { (float)0.040571, 138, 7598 }, - { (float)0.040571, 138, 7736 }, - { (float)0.036339, 142, 7874 }, - { (float)0.036339, 142, 8016 }, - { (float)0.036339, 142, 8158 }, - { (float)0.036339, 142, 8300 }, - { (float)0.032139, 146, 8442 }, - { (float)0.032139, 146, 8588 }, - { (float)0.032139, 146, 8734 }, - { (float)0.032139, 146, 8880 }, - { (float)0.027947, 150, 9026 }, - { (float)0.027947, 150, 9176 }, - { (float)0.027947, 150, 9326 }, - { (float)0.023739, 154, 9476 }, - { (float)0.023739, 154, 9630 }, - { (float)0.023739, 154, 9784 }, - { (float)0.023739, 154, 9938 }, - { (float)0.019504, 158, 10092 }, - { (float)0.019504, 158, 10250 }, - { (float)0.019504, 158, 10408 }, - { (float)0.016976, 161, 10566 }, - { (float)0.016976, 161, 10727 }, - { (float)0.016976, 161, 10888 }, - { (float)0.016976, 161, 11049 }, - { (float)0.012639, 165, 11210 }, - { (float)0.012639, 165, 11375 }, - { (float)0.012639, 165, 11540 }, - { (float)0.009991, 168, 11705 }, - { (float)0.009991, 168, 11873 }, - { (float)0.009991, 168, 12041 }, - { (float)0.009016, 170, 12209 }, - { (float)0.009016, 170, 12379 }, - { (float)0.009016, 170, 12549 }, - { (float)0.006217, 173, 12719 }, - { (float)0.006217, 173, 12892 }, - { (float)0.005097, 175, 13065 }, - { (float)0.005097, 175, 13240 }, - { (float)0.005097, 175, 13415 }, - { (float)0.003909, 177, 13590 }, - { (float)0.003909, 177, 13767 }, - { (float)0.002340, 177, 13944 }, - { (float)0.002389, 170, 14121 }, - { (float)0.001068, 164, 14291 }, - { (float)0.001653, 157, 14455 }, - { (float)0.000717, 150, 14612 }, - { (float)0.001614, 143, 14762 }, - { (float)0.000270, 136, 14905 }, - { (float)0.000484, 129, 15041 }, - { (float)0.001103, 123, 15170 }, - { (float)0.001242, 115, 15293 }, - { (float)0.001188, 109, 15408 }, - { (float)0.001011, 103, 15517 }, - { (float)0.000709, 97, 15620 }, - { (float)0.000301, 89, 15717 }, - { (float)0.002416, 82, 15806 }, - { (float)0.003251, 76, 15888 }, - { (float)0.003246, 69, 15964 }, - { (float)0.004141, 62, 16033 }, - { (float)0.005963, 55, 16095 }, - { (float)0.008839, 47, 16150 }, - { (float)0.010490, 40, 16197 }, - { (float)0.016994, 31, 16237 }, - { (float)0.023659, 21, 16268 }, +#define UV_SQSIZ (float)0.003500 +#define UV_NDIVS 16289 +#define UV_VSTART (float)0.016940 +#define UV_NVS 163 +static const struct +{ + float ustart; + short nus, ncum; +} uv_row[UV_NVS] = { + {(float)0.247663, 4, 0}, {(float)0.243779, 6, 4}, + {(float)0.241684, 7, 10}, {(float)0.237874, 9, 17}, + {(float)0.235906, 10, 26}, {(float)0.232153, 12, 36}, + {(float)0.228352, 14, 48}, {(float)0.226259, 15, 62}, + {(float)0.222371, 17, 77}, {(float)0.220410, 18, 94}, + {(float)0.214710, 21, 112}, {(float)0.212714, 22, 133}, + {(float)0.210721, 23, 155}, {(float)0.204976, 26, 178}, + {(float)0.202986, 27, 204}, {(float)0.199245, 29, 231}, + {(float)0.195525, 31, 260}, {(float)0.193560, 32, 291}, + {(float)0.189878, 34, 323}, {(float)0.186216, 36, 357}, + {(float)0.186216, 36, 393}, {(float)0.182592, 38, 429}, + {(float)0.179003, 40, 467}, {(float)0.175466, 42, 507}, + {(float)0.172001, 44, 549}, {(float)0.172001, 44, 593}, + {(float)0.168612, 46, 637}, {(float)0.168612, 46, 683}, + {(float)0.163575, 49, 729}, {(float)0.158642, 52, 778}, + {(float)0.158642, 52, 830}, {(float)0.158642, 52, 882}, + {(float)0.153815, 55, 934}, {(float)0.153815, 55, 989}, + {(float)0.149097, 58, 1044}, {(float)0.149097, 58, 1102}, + {(float)0.142746, 62, 1160}, {(float)0.142746, 62, 1222}, + {(float)0.142746, 62, 1284}, {(float)0.138270, 65, 1346}, + {(float)0.138270, 65, 1411}, {(float)0.138270, 65, 1476}, + {(float)0.132166, 69, 1541}, {(float)0.132166, 69, 1610}, + {(float)0.126204, 73, 1679}, {(float)0.126204, 73, 1752}, + {(float)0.126204, 73, 1825}, {(float)0.120381, 77, 1898}, + {(float)0.120381, 77, 1975}, {(float)0.120381, 77, 2052}, + {(float)0.120381, 77, 2129}, {(float)0.112962, 82, 2206}, + {(float)0.112962, 82, 2288}, {(float)0.112962, 82, 2370}, + {(float)0.107450, 86, 2452}, {(float)0.107450, 86, 2538}, + {(float)0.107450, 86, 2624}, {(float)0.107450, 86, 2710}, + {(float)0.100343, 91, 2796}, {(float)0.100343, 91, 2887}, + {(float)0.100343, 91, 2978}, {(float)0.095126, 95, 3069}, + {(float)0.095126, 95, 3164}, {(float)0.095126, 95, 3259}, + {(float)0.095126, 95, 3354}, {(float)0.088276, 100, 3449}, + {(float)0.088276, 100, 3549}, {(float)0.088276, 100, 3649}, + {(float)0.088276, 100, 3749}, {(float)0.081523, 105, 3849}, + {(float)0.081523, 105, 3954}, {(float)0.081523, 105, 4059}, + {(float)0.081523, 105, 4164}, {(float)0.074861, 110, 4269}, + {(float)0.074861, 110, 4379}, {(float)0.074861, 110, 4489}, + {(float)0.074861, 110, 4599}, {(float)0.068290, 115, 4709}, + {(float)0.068290, 115, 4824}, {(float)0.068290, 115, 4939}, + {(float)0.068290, 115, 5054}, {(float)0.063573, 119, 5169}, + {(float)0.063573, 119, 5288}, {(float)0.063573, 119, 5407}, + {(float)0.063573, 119, 5526}, {(float)0.057219, 124, 5645}, + {(float)0.057219, 124, 5769}, {(float)0.057219, 124, 5893}, + {(float)0.057219, 124, 6017}, {(float)0.050985, 129, 6141}, + {(float)0.050985, 129, 6270}, {(float)0.050985, 129, 6399}, + {(float)0.050985, 129, 6528}, {(float)0.050985, 129, 6657}, + {(float)0.044859, 134, 6786}, {(float)0.044859, 134, 6920}, + {(float)0.044859, 134, 7054}, {(float)0.044859, 134, 7188}, + {(float)0.040571, 138, 7322}, {(float)0.040571, 138, 7460}, + {(float)0.040571, 138, 7598}, {(float)0.040571, 138, 7736}, + {(float)0.036339, 142, 7874}, {(float)0.036339, 142, 8016}, + {(float)0.036339, 142, 8158}, {(float)0.036339, 142, 8300}, + {(float)0.032139, 146, 8442}, {(float)0.032139, 146, 8588}, + {(float)0.032139, 146, 8734}, {(float)0.032139, 146, 8880}, + {(float)0.027947, 150, 9026}, {(float)0.027947, 150, 9176}, + {(float)0.027947, 150, 9326}, {(float)0.023739, 154, 9476}, + {(float)0.023739, 154, 9630}, {(float)0.023739, 154, 9784}, + {(float)0.023739, 154, 9938}, {(float)0.019504, 158, 10092}, + {(float)0.019504, 158, 10250}, {(float)0.019504, 158, 10408}, + {(float)0.016976, 161, 10566}, {(float)0.016976, 161, 10727}, + {(float)0.016976, 161, 10888}, {(float)0.016976, 161, 11049}, + {(float)0.012639, 165, 11210}, {(float)0.012639, 165, 11375}, + {(float)0.012639, 165, 11540}, {(float)0.009991, 168, 11705}, + {(float)0.009991, 168, 11873}, {(float)0.009991, 168, 12041}, + {(float)0.009016, 170, 12209}, {(float)0.009016, 170, 12379}, + {(float)0.009016, 170, 12549}, {(float)0.006217, 173, 12719}, + {(float)0.006217, 173, 12892}, {(float)0.005097, 175, 13065}, + {(float)0.005097, 175, 13240}, {(float)0.005097, 175, 13415}, + {(float)0.003909, 177, 13590}, {(float)0.003909, 177, 13767}, + {(float)0.002340, 177, 13944}, {(float)0.002389, 170, 14121}, + {(float)0.001068, 164, 14291}, {(float)0.001653, 157, 14455}, + {(float)0.000717, 150, 14612}, {(float)0.001614, 143, 14762}, + {(float)0.000270, 136, 14905}, {(float)0.000484, 129, 15041}, + {(float)0.001103, 123, 15170}, {(float)0.001242, 115, 15293}, + {(float)0.001188, 109, 15408}, {(float)0.001011, 103, 15517}, + {(float)0.000709, 97, 15620}, {(float)0.000301, 89, 15717}, + {(float)0.002416, 82, 15806}, {(float)0.003251, 76, 15888}, + {(float)0.003246, 69, 15964}, {(float)0.004141, 62, 16033}, + {(float)0.005963, 55, 16095}, {(float)0.008839, 47, 16150}, + {(float)0.010490, 40, 16197}, {(float)0.016994, 31, 16237}, + {(float)0.023659, 21, 16268}, }; |