1 /*
2
3 rl2tiff -- TIFF / GeoTIFF related functions
4
5 version 0.1, 2013 April 5
6
7 Author: Sandro Furieri a.furieri@lqt.it
8
9 -----------------------------------------------------------------------------
10
11 Version: MPL 1.1/GPL 2.0/LGPL 2.1
12
13 The contents of this file are subject to the Mozilla Public License Version
14 1.1 (the "License"); you may not use this file except in compliance with
15 the License. You may obtain a copy of the License at
16 http://www.mozilla.org/MPL/
17
18 Software distributed under the License is distributed on an "AS IS" basis,
19 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20 for the specific language governing rights and limitations under the
21 License.
22
23 The Original Code is the SpatiaLite library
24
25 The Initial Developer of the Original Code is Alessandro Furieri
26
27 Portions created by the Initial Developer are Copyright (C) 2008-2013
28 the Initial Developer. All Rights Reserved.
29
30 Alternatively, the contents of this file may be used under the terms of
31 either the GNU General Public License Version 2 or later (the "GPL"), or
32 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
33 in which case the provisions of the GPL or the LGPL are applicable instead
34 of those above. If you wish to allow use of your version of this file only
35 under the terms of either the GPL or the LGPL, and not to allow others to
36 use your version of this file under the terms of the MPL, indicate your
37 decision by deleting the provisions above and replace them with the notice
38 and other provisions required by the GPL or the LGPL. If you do not delete
39 the provisions above, a recipient may use your version of this file under
40 the terms of any one of the MPL, the GPL or the LGPL.
41
42 */
43
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <float.h>
48 #include <inttypes.h>
49
50 #include "rasterlite2/sqlite.h"
51
52 #include "config.h"
53
54 #include "rasterlite2/rasterlite2.h"
55 #include "rasterlite2_private.h"
56 #include "rasterlite2/rl2tiff.h"
57
58 struct memfile
59 {
60 /* a struct emulating a file [memory mapped] */
61 unsigned char *buffer;
62 int malloc_block;
63 tsize_t size;
64 tsize_t eof;
65 toff_t current;
66 };
67
68 static void
memory_realloc(struct memfile * mem,tsize_t req_size)69 memory_realloc (struct memfile *mem, tsize_t req_size)
70 {
71 /* expanding the allocated memory */
72 unsigned char *new_buffer;
73 tsize_t new_size = mem->size;
74 while (new_size <= req_size)
75 new_size += mem->malloc_block;
76 new_buffer = realloc (mem->buffer, new_size);
77 if (!new_buffer)
78 return;
79 mem->buffer = new_buffer;
80 memset (mem->buffer + mem->size, '\0', new_size - mem->size);
81 mem->size = new_size;
82 }
83
84 static tsize_t
memory_readproc(thandle_t clientdata,tdata_t data,tsize_t size)85 memory_readproc (thandle_t clientdata, tdata_t data, tsize_t size)
86 {
87 /* emulating the read() function */
88 struct memfile *mem = clientdata;
89 tsize_t len;
90 if (mem->current >= (toff_t) mem->eof)
91 return 0;
92 len = size;
93 if ((mem->current + size) >= (toff_t) mem->eof)
94 len = (tsize_t) (mem->eof - mem->current);
95 memcpy (data, mem->buffer + mem->current, len);
96 mem->current += len;
97 return len;
98 }
99
100 static tsize_t
memory_writeproc(thandle_t clientdata,tdata_t data,tsize_t size)101 memory_writeproc (thandle_t clientdata, tdata_t data, tsize_t size)
102 {
103 /* emulating the write() function */
104 struct memfile *mem = clientdata;
105 if ((mem->current + size) >= (toff_t) mem->size)
106 memory_realloc (mem, mem->current + size);
107 if ((mem->current + size) >= (toff_t) mem->size)
108 return -1;
109 memcpy (mem->buffer + mem->current, (unsigned char *) data, size);
110 mem->current += size;
111 if (mem->current > (toff_t) mem->eof)
112 mem->eof = (tsize_t) (mem->current);
113 return size;
114 }
115
116 static toff_t
memory_seekproc(thandle_t clientdata,toff_t offset,int whence)117 memory_seekproc (thandle_t clientdata, toff_t offset, int whence)
118 {
119 /* emulating the lseek() function */
120 struct memfile *mem = clientdata;
121 switch (whence)
122 {
123 case SEEK_CUR:
124 if ((int) (mem->current + offset) < 0)
125 return (toff_t) - 1;
126 mem->current += offset;
127 if ((toff_t) mem->eof < mem->current)
128 mem->eof = (tsize_t) (mem->current);
129 break;
130 case SEEK_END:
131 if ((int) (mem->eof + offset) < 0)
132 return (toff_t) - 1;
133 mem->current = mem->eof + offset;
134 if ((toff_t) mem->eof < mem->current)
135 mem->eof = (tsize_t) (mem->current);
136 break;
137 case SEEK_SET:
138 default:
139 if ((int) offset < 0)
140 return (toff_t) - 1;
141 mem->current = offset;
142 if ((toff_t) mem->eof < mem->current)
143 mem->eof = (tsize_t) (mem->current);
144 break;
145 };
146 return mem->current;
147 }
148
149 static int
closeproc(thandle_t clientdata)150 closeproc (thandle_t clientdata)
151 {
152 /* emulating the close() function */
153 if (clientdata)
154 return 0; /* does absolutely nothing - required in order to suppress warnings */
155 return 0;
156 }
157
158 static toff_t
memory_sizeproc(thandle_t clientdata)159 memory_sizeproc (thandle_t clientdata)
160 {
161 /* returning the pseudo-file current size */
162 struct memfile *mem = clientdata;
163 return mem->eof;
164 }
165
166 static int
mapproc(thandle_t clientdata,tdata_t * data,toff_t * offset)167 mapproc (thandle_t clientdata, tdata_t * data, toff_t * offset)
168 {
169 if (clientdata || data || offset)
170 return 0; /* does absolutely nothing - required in order to suppress warnings */
171 return 0;
172 }
173
174 static void
unmapproc(thandle_t clientdata,tdata_t data,toff_t offset)175 unmapproc (thandle_t clientdata, tdata_t data, toff_t offset)
176 {
177 if (clientdata || data || offset)
178 return; /* does absolutely nothing - required in order to suppress warnings */
179 return;
180 }
181
182 static int
183 read_from_tiff (rl2PrivTiffOriginPtr origin, unsigned short width,
184 unsigned short height, unsigned char sample_type,
185 unsigned char pixel_type, unsigned char num_bands,
186 unsigned int startRow, unsigned int startCol,
187 unsigned char **pixels, int *pixels_sz, rl2PalettePtr palette);
188
189 static rl2PrivTiffOriginPtr
create_tiff_origin(const char * path,unsigned char force_sample_type,unsigned char force_pixel_type,unsigned char force_num_bands)190 create_tiff_origin (const char *path, unsigned char force_sample_type,
191 unsigned char force_pixel_type,
192 unsigned char force_num_bands)
193 {
194 /* creating an uninitialized TIFF origin */
195 int len;
196 rl2PrivTiffOriginPtr origin;
197 if (path == NULL)
198 return NULL;
199 origin = malloc (sizeof (rl2PrivTiffOrigin));
200 if (origin == NULL)
201 return NULL;
202
203 len = strlen (path);
204 origin->path = malloc (len + 1);
205 strcpy (origin->path, path);
206 origin->tfw_path = NULL;
207 origin->isGeoTiff = 0;
208 origin->in = (TIFF *) 0;
209 origin->tileWidth = 0;
210 origin->tileHeight = 0;
211 origin->rowsPerStrip = 0;
212 origin->maxPalette = 0;
213 origin->red = NULL;
214 origin->green = NULL;
215 origin->blue = NULL;
216 origin->remapMaxPalette = 0;
217 origin->remapRed = NULL;
218 origin->remapGreen = NULL;
219 origin->remapBlue = NULL;
220 origin->isGeoReferenced = 0;
221 origin->Srid = -1;
222 origin->srsName = NULL;
223 origin->proj4text = NULL;
224 origin->forced_sample_type = force_sample_type;
225 origin->forced_pixel_type = force_pixel_type;
226 origin->forced_num_bands = force_num_bands;
227 origin->forced_conversion = RL2_CONVERT_NO;
228 return origin;
229 }
230
231 static int
alloc_palette(rl2PrivTiffOriginPtr tiff,int max_palette)232 alloc_palette (rl2PrivTiffOriginPtr tiff, int max_palette)
233 {
234 /* allocating an empty Palette */
235 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
236 int i;
237
238 if (origin == NULL)
239 return 0;
240 if (max_palette < 1 || max_palette > 256)
241 return 0;
242 origin->maxPalette = max_palette;
243 origin->red = malloc (max_palette);
244 if (origin->red == NULL)
245 return 0;
246 origin->green = malloc (max_palette);
247 if (origin->green == NULL)
248 {
249 free (origin->red);
250 return 0;
251 }
252 origin->blue = malloc (max_palette);
253 if (origin->blue == NULL)
254 {
255 free (origin->red);
256 free (origin->green);
257 return 0;
258 }
259 for (i = 0; i < max_palette; i++)
260 {
261 origin->red[i] = 0;
262 origin->green[i] = 0;
263 origin->blue[i] = 0;
264 }
265 return 1;
266 }
267
268 RL2_DECLARE void
rl2_destroy_tiff_origin(rl2TiffOriginPtr tiff)269 rl2_destroy_tiff_origin (rl2TiffOriginPtr tiff)
270 {
271 /* memory cleanup - destroying a TIFF origin */
272 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
273 if (origin == NULL)
274 return;
275 if (origin->in != (TIFF *) 0)
276 TIFFClose (origin->in);
277 if (origin->path != NULL)
278 free (origin->path);
279 if (origin->tfw_path != NULL)
280 free (origin->tfw_path);
281 if (origin->red != NULL)
282 free (origin->red);
283 if (origin->green != NULL)
284 free (origin->green);
285 if (origin->blue != NULL)
286 free (origin->blue);
287 if (origin->remapRed != NULL)
288 free (origin->remapRed);
289 if (origin->remapGreen != NULL)
290 free (origin->remapGreen);
291 if (origin->remapBlue != NULL)
292 free (origin->remapBlue);
293 if (origin->srsName != NULL)
294 free (origin->srsName);
295 if (origin->proj4text != NULL)
296 free (origin->proj4text);
297 free (origin);
298 }
299
300 static void
origin_set_tfw_path(const char * path,rl2PrivTiffOriginPtr origin)301 origin_set_tfw_path (const char *path, rl2PrivTiffOriginPtr origin)
302 {
303 /* building the TFW path (WorldFile) */
304 char *tfw;
305 const char *x = NULL;
306 const char *p = path;
307 int len = strlen (path);
308 len -= 1;
309 while (*p != '\0')
310 {
311 if (*p == '.')
312 x = p;
313 p++;
314 }
315 if (x > path)
316 len = x - path;
317 tfw = malloc (len + 5);
318 memcpy (tfw, path, len);
319 memcpy (tfw + len, ".tfw", 4);
320 *(tfw + len + 4) = '\0';
321 origin->tfw_path = tfw;
322 }
323
324 static int
is_valid_float(char * str)325 is_valid_float (char *str)
326 {
327 /* testing for a valid worlodfile float value */
328 char *p = str;
329 int point = 0;
330 int sign = 0;
331 int digit = 0;
332 int len = strlen (str);
333 int i;
334
335 for (i = len - 1; i >= 0; i--)
336 {
337 /* suppressing any trailing blank */
338 if (str[i] == ' ' || str[i] == '\t' || str[i] == '\r')
339 str[i] = '\0';
340 else
341 break;
342 }
343
344 while (1)
345 {
346 /* skipping leading blanks */
347 if (*p != ' ' && *p != '\t')
348 break;
349 p++;
350 }
351
352 /* testing for a well formatted float */
353 while (1)
354 {
355 if (*p == '\0')
356 break;
357 if (*p >= '0' && *p <= '9')
358 digit++;
359 else if (*p == '.')
360 point++;
361 else if (*p == ',')
362 {
363 *p = '.';
364 point++;
365 }
366 else if (*p == '+' || *p == '-')
367 {
368 if (digit == 0 && point == 0 && sign == 0)
369 ;
370 else
371 return 0;
372 }
373 else
374 return 0;
375 p++;
376 }
377 if (digit > 0 && sign <= 1 && point <= 1)
378 return 1;
379 return 0;
380 }
381
382 RL2_PRIVATE int
parse_worldfile(FILE * in,double * px,double * py,double * pres_x,double * pres_y)383 parse_worldfile (FILE * in, double *px, double *py, double *pres_x,
384 double *pres_y)
385 {
386 /* attemtping to parse a WorldFile */
387 int line_no = 0;
388 int ok_res_x = 0;
389 int ok_res_y = 0;
390 int ok_x = 0;
391 int ok_y = 0;
392 char buf[1024];
393 char *p = buf;
394 double x;
395 double y;
396 double res_x;
397 double res_y;
398
399 if (in == NULL)
400 return 0;
401
402 while (1)
403 {
404 int c = getc (in);
405 if (c == '\n' || c == EOF)
406 {
407 *p = '\0';
408 if (line_no == 0)
409 {
410 if (is_valid_float (buf))
411 {
412 res_x = atof (buf);
413 ok_res_x = 1;
414 }
415 }
416 if (line_no == 3)
417 {
418 if (is_valid_float (buf))
419 {
420 res_y = atof (buf) * -1.0;
421 ok_res_y = 1;
422 }
423 }
424 if (line_no == 4)
425 {
426 if (is_valid_float (buf))
427 {
428 x = atof (buf);
429 ok_x = 1;
430 }
431 }
432 if (line_no == 5)
433 {
434 if (is_valid_float (buf))
435 {
436 y = atof (buf);
437 ok_y = 1;
438 }
439 }
440 if (c == EOF)
441 break;
442 p = buf;
443 line_no++;
444 continue;
445 }
446 *p++ = c;
447 }
448
449 if (ok_x && ok_y && ok_res_x && ok_res_y)
450 {
451 *px = x;
452 *py = y;
453 *pres_x = res_x;
454 *pres_y = res_y;
455 return 1;
456 }
457 return 0;
458 }
459
460 static void
worldfile_tiff_origin(const char * path,rl2PrivTiffOriginPtr origin,int srid)461 worldfile_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin, int srid)
462 {
463 /* attempting to retrieve georeferencing from a TIFF+TFW origin */
464 FILE *tfw = NULL;
465 double res_x;
466 double res_y;
467 double x;
468 double y;
469
470 origin_set_tfw_path (path, origin);
471 tfw = fopen (origin->tfw_path, "r");
472 if (tfw == NULL)
473 goto error;
474 if (!parse_worldfile (tfw, &x, &y, &res_x, &res_y))
475 goto error;
476 fclose (tfw);
477 origin->Srid = srid;
478 origin->hResolution = res_x;
479 origin->vResolution = res_y;
480 origin->minX = x;
481 origin->maxY = y;
482 origin->isGeoReferenced = 1;
483 return;
484
485 error:
486 if (tfw != NULL)
487 fclose (tfw);
488 if (origin->tfw_path != NULL)
489 free (origin->tfw_path);
490 origin->tfw_path = NULL;
491 }
492
493 static void
geo_tiff_origin(const char * path,rl2PrivTiffOriginPtr origin,int force_srid)494 geo_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin, int force_srid)
495 {
496 /* attempting to retrieve georeferencing from a GeoTIFF origin */
497 uint32 width = 0;
498 uint32 height = 0;
499 double cx;
500 double cy;
501 GTIFDefn definition;
502 char *pString;
503 int len;
504 TIFF *in = (TIFF *) 0;
505 GTIF *gtif = (GTIF *) 0;
506
507 /* suppressing TIFF messages */
508 TIFFSetErrorHandler (NULL);
509 TIFFSetWarningHandler (NULL);
510
511 /* reading from file */
512 in = XTIFFOpen (path, "r");
513 if (in == NULL)
514 goto error;
515 gtif = GTIFNew (in);
516 if (gtif == NULL)
517 goto error;
518
519 if (!GTIFGetDefn (gtif, &definition))
520 goto error;
521 /* retrieving the EPSG code */
522 if (definition.PCS == 32767)
523 {
524 if (definition.GCS != 32767)
525 origin->Srid = definition.GCS;
526 }
527 else
528 origin->Srid = definition.PCS;
529 if (origin->Srid <= 0)
530 {
531 origin->Srid = force_srid;
532 if (origin->Srid <= 0)
533 goto error;
534 }
535 if (definition.PCS == 32767)
536 {
537 /* Get the GCS name if possible */
538 pString = NULL;
539 GTIFGetGCSInfo (definition.GCS, &pString, NULL, NULL, NULL);
540 if (pString != NULL)
541 {
542 len = strlen (pString);
543 origin->srsName = malloc (len + 1);
544 strcpy (origin->srsName, pString);
545 CPLFree (pString);
546 }
547 }
548 else
549 {
550 /* Get the PCS name if possible */
551 pString = NULL;
552 GTIFGetPCSInfo (definition.PCS, &pString, NULL, NULL, NULL);
553 if (pString != NULL)
554 {
555 len = strlen (pString);
556 origin->srsName = malloc (len + 1);
557 strcpy (origin->srsName, pString);
558 CPLFree (pString);
559 }
560 }
561 /* retrieving the PROJ.4 params */
562 pString = GTIFGetProj4Defn (&definition);
563 if (pString != NULL)
564 {
565 len = strlen (pString);
566 origin->proj4text = malloc (len + 1);
567 strcpy (origin->proj4text, pString);
568 CPLFree (pString);
569 }
570
571 /* retrieving the TIFF dimensions */
572 TIFFGetField (in, TIFFTAG_IMAGELENGTH, &height);
573 TIFFGetField (in, TIFFTAG_IMAGEWIDTH, &width);
574
575 /* computing the corners coords */
576 cx = 0.0;
577 cy = 0.0;
578 GTIFImageToPCS (gtif, &cx, &cy);
579 origin->minX = cx;
580 origin->maxY = cy;
581 cx = 0.0;
582 cy = height;
583 GTIFImageToPCS (gtif, &cx, &cy);
584 origin->minY = cy;
585 cx = width;
586 cy = 0.0;
587 GTIFImageToPCS (gtif, &cx, &cy);
588 origin->maxX = cx;
589
590 /* computing the pixel resolution */
591 origin->hResolution = (origin->maxX - origin->minX) / (double) width;
592 origin->vResolution = (origin->maxY - origin->minY) / (double) height;
593 origin->isGeoReferenced = 1;
594 origin->isGeoTiff = 1;
595
596 error:
597 if (in != (TIFF *) 0)
598 XTIFFClose (in);
599 if (gtif != (GTIF *) 0)
600 GTIFFree (gtif);
601 }
602
603 static int
check_grayscale_palette(rl2PrivTiffOriginPtr origin)604 check_grayscale_palette (rl2PrivTiffOriginPtr origin)
605 {
606 /* checking if a Palette actually is a Grayscale Palette */
607 int i;
608 if (origin->maxPalette == 0 || origin->maxPalette > 256)
609 return 0;
610 for (i = 0; i < origin->maxPalette; i++)
611 {
612 if (origin->red[i] == origin->green[i]
613 && origin->red[i] == origin->blue[i])
614 ;
615 else
616 return 0;
617 }
618 return 1;
619 }
620
621 static int
check_tiff_origin_pixel_conversion(rl2PrivTiffOriginPtr origin)622 check_tiff_origin_pixel_conversion (rl2PrivTiffOriginPtr origin)
623 {
624 /* check if the Color-Space conversion could be accepted */
625 if (origin->forced_sample_type == RL2_SAMPLE_UNKNOWN)
626 {
627 if (origin->sampleFormat == SAMPLEFORMAT_INT)
628 {
629 if (origin->bitsPerSample == 8)
630 origin->forced_sample_type = RL2_SAMPLE_INT8;
631 if (origin->bitsPerSample == 16)
632 origin->forced_sample_type = RL2_SAMPLE_INT16;
633 if (origin->bitsPerSample == 32)
634 origin->forced_sample_type = RL2_SAMPLE_INT32;
635 }
636 else if (origin->sampleFormat == SAMPLEFORMAT_UINT)
637 {
638 if (origin->bitsPerSample == 1)
639 origin->forced_sample_type = RL2_SAMPLE_1_BIT;
640 if (origin->bitsPerSample == 2)
641 origin->forced_sample_type = RL2_SAMPLE_2_BIT;
642 if (origin->bitsPerSample == 4)
643 origin->forced_sample_type = RL2_SAMPLE_4_BIT;
644 if (origin->bitsPerSample == 8)
645 origin->forced_sample_type = RL2_SAMPLE_UINT8;
646 if (origin->bitsPerSample == 16)
647 origin->forced_sample_type = RL2_SAMPLE_UINT16;
648 if (origin->bitsPerSample == 32)
649 origin->forced_sample_type = RL2_SAMPLE_UINT32;
650 }
651 else if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP)
652 {
653 if (origin->bitsPerSample == 32)
654 origin->forced_sample_type = RL2_SAMPLE_FLOAT;
655 if (origin->bitsPerSample == 64)
656 origin->forced_sample_type = RL2_SAMPLE_DOUBLE;
657 }
658 }
659 if (origin->forced_pixel_type == RL2_PIXEL_UNKNOWN)
660 {
661 if (origin->sampleFormat == SAMPLEFORMAT_UINT
662 && origin->photometric == PHOTOMETRIC_RGB)
663 {
664 if (origin->samplesPerPixel == 3)
665 origin->forced_pixel_type = RL2_PIXEL_RGB;
666 else
667 origin->forced_pixel_type = RL2_PIXEL_MULTIBAND;
668 }
669 if (origin->sampleFormat == SAMPLEFORMAT_UINT
670 && origin->samplesPerPixel == 1
671 && origin->photometric < PHOTOMETRIC_RGB
672 && origin->bitsPerSample > 1)
673 origin->forced_pixel_type = RL2_PIXEL_GRAYSCALE;
674 if (origin->sampleFormat == SAMPLEFORMAT_UINT
675 && origin->samplesPerPixel == 1
676 && origin->photometric == PHOTOMETRIC_PALETTE
677 && origin->bitsPerSample <= 8)
678 origin->forced_pixel_type = RL2_PIXEL_PALETTE;
679 if (origin->sampleFormat == SAMPLEFORMAT_UINT
680 && origin->samplesPerPixel == 1
681 && origin->photometric <= PHOTOMETRIC_RGB
682 && origin->bitsPerSample == 1)
683 origin->forced_pixel_type = RL2_PIXEL_MONOCHROME;
684 if (origin->sampleFormat == SAMPLEFORMAT_INT
685 && origin->samplesPerPixel == 1
686 && origin->photometric < PHOTOMETRIC_RGB
687 && origin->bitsPerSample == 8)
688 origin->forced_pixel_type = RL2_PIXEL_DATAGRID;
689 if (origin->sampleFormat == SAMPLEFORMAT_INT
690 && origin->samplesPerPixel == 1
691 && origin->photometric < PHOTOMETRIC_RGB
692 && origin->bitsPerSample == 16)
693 origin->forced_pixel_type = RL2_PIXEL_DATAGRID;
694 if (origin->sampleFormat == SAMPLEFORMAT_INT
695 && origin->samplesPerPixel == 1
696 && origin->photometric < PHOTOMETRIC_RGB
697 && origin->bitsPerSample == 32)
698 origin->forced_pixel_type = RL2_PIXEL_DATAGRID;
699 if (origin->sampleFormat == SAMPLEFORMAT_UINT
700 && origin->samplesPerPixel == 1
701 && origin->photometric < PHOTOMETRIC_RGB
702 && origin->bitsPerSample == 32)
703 origin->forced_pixel_type = RL2_PIXEL_DATAGRID;
704 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
705 && origin->samplesPerPixel == 1
706 && origin->photometric < PHOTOMETRIC_RGB
707 && origin->bitsPerSample == 32)
708 origin->forced_pixel_type = RL2_PIXEL_DATAGRID;
709 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
710 && origin->samplesPerPixel == 1
711 && origin->photometric < PHOTOMETRIC_RGB
712 && origin->bitsPerSample == 64)
713 origin->forced_pixel_type = RL2_PIXEL_DATAGRID;
714 }
715 if (origin->forced_num_bands == RL2_BANDS_UNKNOWN)
716 origin->forced_num_bands = origin->samplesPerPixel;
717
718 if (origin->forced_sample_type == RL2_SAMPLE_UINT8
719 && origin->forced_pixel_type == RL2_PIXEL_RGB
720 && origin->forced_num_bands == 3)
721 {
722 /* RGB color-space */
723 if (origin->sampleFormat == SAMPLEFORMAT_UINT
724 && origin->samplesPerPixel == 3
725 && origin->photometric == PHOTOMETRIC_RGB)
726 return 1;
727 if (origin->sampleFormat == SAMPLEFORMAT_UINT
728 && origin->samplesPerPixel == 1
729 && origin->photometric < PHOTOMETRIC_RGB)
730 {
731 origin->forced_conversion = RL2_CONVERT_GRAYSCALE_TO_RGB;
732 return 1;
733 }
734 if (origin->sampleFormat == SAMPLEFORMAT_UINT
735 && origin->samplesPerPixel == 1
736 && origin->photometric == PHOTOMETRIC_PALETTE
737 && origin->bitsPerSample <= 8)
738 {
739 origin->forced_conversion = RL2_CONVERT_PALETTE_TO_RGB;
740 return 1;
741 }
742 }
743 if (origin->forced_sample_type == RL2_SAMPLE_UINT16
744 && origin->forced_pixel_type == RL2_PIXEL_RGB
745 && origin->forced_num_bands == 3)
746 {
747 /* RGB color-space */
748 if (origin->sampleFormat == SAMPLEFORMAT_UINT
749 && origin->samplesPerPixel == 3
750 && origin->photometric == PHOTOMETRIC_RGB)
751 return 1;
752 }
753 if (origin->forced_sample_type == RL2_SAMPLE_UINT8
754 && origin->forced_pixel_type == RL2_PIXEL_MULTIBAND)
755 {
756 /* MULTIBAND color-space */
757 if (origin->sampleFormat == SAMPLEFORMAT_UINT
758 && origin->samplesPerPixel == origin->forced_num_bands
759 && origin->photometric == PHOTOMETRIC_RGB)
760 return 1;
761 }
762 if (origin->forced_sample_type == RL2_SAMPLE_UINT16
763 && origin->forced_pixel_type == RL2_PIXEL_MULTIBAND)
764 {
765 /* MULTIBAND color-space */
766 if (origin->sampleFormat == SAMPLEFORMAT_UINT
767 && origin->samplesPerPixel == origin->forced_num_bands
768 && origin->photometric == PHOTOMETRIC_RGB)
769 return 1;
770 }
771 if (origin->forced_sample_type == RL2_SAMPLE_UINT8
772 && origin->forced_pixel_type == RL2_PIXEL_GRAYSCALE
773 && origin->forced_num_bands == 1)
774 {
775 /* GRAYSCALE color-space */
776 if (origin->sampleFormat == SAMPLEFORMAT_UINT
777 && origin->samplesPerPixel == 1
778 && origin->photometric < PHOTOMETRIC_RGB
779 && origin->bitsPerSample > 1)
780 return 1;
781 if (origin->sampleFormat == SAMPLEFORMAT_UINT
782 && origin->samplesPerPixel == 3
783 && origin->photometric == PHOTOMETRIC_RGB)
784 {
785 origin->forced_conversion = RL2_CONVERT_RGB_TO_GRAYSCALE;
786 return 1;
787 }
788 if (origin->sampleFormat == SAMPLEFORMAT_UINT
789 && origin->samplesPerPixel == 1
790 && origin->photometric == PHOTOMETRIC_PALETTE
791 && origin->bitsPerSample <= 8 && check_grayscale_palette (origin))
792 {
793 origin->forced_conversion = RL2_CONVERT_PALETTE_TO_GRAYSCALE;
794 return 1;
795 }
796 }
797 if (origin->forced_sample_type == RL2_SAMPLE_UINT16
798 && origin->forced_pixel_type == RL2_PIXEL_GRAYSCALE
799 && origin->forced_num_bands == 1)
800 {
801 /* GRAYSCALE color-space */
802 if (origin->sampleFormat == SAMPLEFORMAT_UINT
803 && origin->samplesPerPixel == 1
804 && origin->photometric < PHOTOMETRIC_RGB
805 && origin->bitsPerSample > 1)
806 return 1;
807 }
808 if (origin->forced_sample_type == RL2_SAMPLE_UINT8
809 && origin->forced_pixel_type == RL2_PIXEL_PALETTE
810 && origin->forced_num_bands == 1)
811 {
812 /* PALETTE-256 color-space */
813 if (origin->sampleFormat == SAMPLEFORMAT_UINT
814 && origin->samplesPerPixel == 1
815 && origin->photometric == PHOTOMETRIC_PALETTE
816 && origin->bitsPerSample <= 8)
817 return 1;
818 if (origin->sampleFormat == SAMPLEFORMAT_UINT
819 && origin->samplesPerPixel == 1
820 && origin->photometric < PHOTOMETRIC_RGB)
821 {
822 origin->forced_conversion = RL2_CONVERT_GRAYSCALE_TO_PALETTE;
823 return 1;
824 }
825 }
826 if (origin->forced_sample_type == RL2_SAMPLE_4_BIT
827 && origin->forced_pixel_type == RL2_PIXEL_PALETTE
828 && origin->forced_num_bands == 1)
829 {
830 /* PALETTE-16 color-space */
831 if (origin->sampleFormat == SAMPLEFORMAT_UINT
832 && origin->samplesPerPixel == 1
833 && origin->photometric == PHOTOMETRIC_PALETTE
834 && origin->bitsPerSample <= 8)
835 return 1;
836 }
837 if (origin->forced_sample_type == RL2_SAMPLE_2_BIT
838 && origin->forced_pixel_type == RL2_PIXEL_PALETTE
839 && origin->forced_num_bands == 1)
840 {
841 /* PALETTE-4 color-space */
842 if (origin->sampleFormat == SAMPLEFORMAT_UINT
843 && origin->samplesPerPixel == 1
844 && origin->photometric == PHOTOMETRIC_PALETTE
845 && origin->bitsPerSample <= 8)
846 return 1;
847 }
848 if (origin->forced_sample_type == RL2_SAMPLE_1_BIT
849 && origin->forced_pixel_type == RL2_PIXEL_PALETTE
850 && origin->forced_num_bands == 1)
851 {
852 /* PALETTE-2 color-space */
853 if (origin->sampleFormat == SAMPLEFORMAT_UINT
854 && origin->samplesPerPixel == 1
855 && origin->photometric == PHOTOMETRIC_PALETTE
856 && origin->bitsPerSample <= 8)
857 return 1;
858 if (origin->sampleFormat == SAMPLEFORMAT_UINT
859 && origin->samplesPerPixel == 1
860 && origin->photometric <= PHOTOMETRIC_RGB
861 && origin->bitsPerSample == 1)
862 {
863 origin->forced_conversion = RL2_CONVERT_MONOCHROME_TO_PALETTE;
864 return 1;
865 }
866 }
867 if (origin->forced_sample_type == RL2_SAMPLE_1_BIT
868 && origin->forced_pixel_type == RL2_PIXEL_MONOCHROME
869 && origin->forced_num_bands == 1)
870 {
871 /* MONOCHROME color-space */
872 if (origin->sampleFormat == SAMPLEFORMAT_UINT
873 && origin->samplesPerPixel == 1
874 && origin->photometric <= PHOTOMETRIC_RGB
875 && origin->bitsPerSample == 1)
876 return 1;
877 if (origin->sampleFormat == SAMPLEFORMAT_UINT
878 && origin->samplesPerPixel == 1
879 && origin->photometric == PHOTOMETRIC_PALETTE
880 && origin->bitsPerSample <= 8)
881 {
882 origin->forced_conversion = RL2_CONVERT_PALETTE_TO_MONOCHROME;
883 return 1;
884 }
885 }
886 if (origin->forced_sample_type == RL2_SAMPLE_INT8
887 && origin->forced_pixel_type == RL2_PIXEL_DATAGRID
888 && origin->forced_num_bands == 1)
889 {
890 /* INT8 datagrid */
891 if (origin->sampleFormat == SAMPLEFORMAT_INT
892 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
893 return 1;
894 if (origin->sampleFormat == SAMPLEFORMAT_UINT
895 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
896 {
897 origin->forced_conversion = RL2_CONVERT_GRID_UINT8_TO_INT8;
898 return 1;
899 }
900 if (origin->sampleFormat == SAMPLEFORMAT_INT
901 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
902 {
903 origin->forced_conversion = RL2_CONVERT_GRID_INT16_TO_INT8;
904 return 1;
905 }
906 if (origin->sampleFormat == SAMPLEFORMAT_UINT
907 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
908 {
909 origin->forced_conversion = RL2_CONVERT_GRID_UINT16_TO_INT8;
910 return 1;
911 }
912 if (origin->sampleFormat == SAMPLEFORMAT_INT
913 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
914 {
915 origin->forced_conversion = RL2_CONVERT_GRID_INT32_TO_INT8;
916 return 1;
917 }
918 if (origin->sampleFormat == SAMPLEFORMAT_UINT
919 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
920 {
921 origin->forced_conversion = RL2_CONVERT_GRID_UINT32_TO_INT8;
922 return 1;
923 }
924 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
925 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
926 {
927 origin->forced_conversion = RL2_CONVERT_GRID_FLOAT_TO_INT8;
928 return 1;
929 }
930 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
931 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 64)
932 {
933 origin->forced_conversion = RL2_CONVERT_GRID_DOUBLE_TO_INT8;
934 return 1;
935 }
936 }
937 if (origin->forced_sample_type == RL2_SAMPLE_UINT8
938 && origin->forced_pixel_type == RL2_PIXEL_DATAGRID
939 && origin->forced_num_bands == 1)
940 {
941 /* UINT8 datagrid */
942 if (origin->sampleFormat == SAMPLEFORMAT_UINT
943 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
944 return 1;
945 if (origin->sampleFormat == SAMPLEFORMAT_INT
946 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
947 {
948 origin->forced_conversion = RL2_CONVERT_GRID_INT8_TO_UINT8;
949 return 1;
950 }
951 if (origin->sampleFormat == SAMPLEFORMAT_INT
952 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
953 {
954 origin->forced_conversion = RL2_CONVERT_GRID_INT16_TO_UINT8;
955 return 1;
956 }
957 if (origin->sampleFormat == SAMPLEFORMAT_UINT
958 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
959 {
960 origin->forced_conversion = RL2_CONVERT_GRID_UINT16_TO_UINT8;
961 return 1;
962 }
963 if (origin->sampleFormat == SAMPLEFORMAT_INT
964 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
965 {
966 origin->forced_conversion = RL2_CONVERT_GRID_INT32_TO_UINT8;
967 return 1;
968 }
969 if (origin->sampleFormat == SAMPLEFORMAT_UINT
970 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
971 {
972 origin->forced_conversion = RL2_CONVERT_GRID_UINT32_TO_UINT8;
973 return 1;
974 }
975 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
976 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
977 {
978 origin->forced_conversion = RL2_CONVERT_GRID_FLOAT_TO_UINT8;
979 return 1;
980 }
981 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
982 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 64)
983 {
984 origin->forced_conversion = RL2_CONVERT_GRID_DOUBLE_TO_UINT8;
985 return 1;
986 }
987 }
988 if (origin->forced_sample_type == RL2_SAMPLE_INT16
989 && origin->forced_pixel_type == RL2_PIXEL_DATAGRID
990 && origin->forced_num_bands == 1)
991 {
992 /* INT16 datagrid */
993 if (origin->sampleFormat == SAMPLEFORMAT_INT
994 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
995 return 1;
996 if (origin->sampleFormat == SAMPLEFORMAT_UINT
997 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
998 {
999 origin->forced_conversion = RL2_CONVERT_GRID_UINT16_TO_INT16;
1000 return 1;
1001 }
1002 if (origin->sampleFormat == SAMPLEFORMAT_INT
1003 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1004 {
1005 origin->forced_conversion = RL2_CONVERT_GRID_INT8_TO_INT16;
1006 return 1;
1007 }
1008 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1009 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1010 {
1011 origin->forced_conversion = RL2_CONVERT_GRID_UINT8_TO_INT16;
1012 return 1;
1013 }
1014 if (origin->sampleFormat == SAMPLEFORMAT_INT
1015 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1016 {
1017 origin->forced_conversion = RL2_CONVERT_GRID_INT32_TO_INT16;
1018 return 1;
1019 }
1020 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1021 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1022 {
1023 origin->forced_conversion = RL2_CONVERT_GRID_UINT32_TO_INT16;
1024 return 1;
1025 }
1026 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1027 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1028 {
1029 origin->forced_conversion = RL2_CONVERT_GRID_FLOAT_TO_INT16;
1030 return 1;
1031 }
1032 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1033 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 64)
1034 {
1035 origin->forced_conversion = RL2_CONVERT_GRID_DOUBLE_TO_INT16;
1036 return 1;
1037 }
1038 }
1039 if (origin->forced_sample_type == RL2_SAMPLE_UINT16
1040 && origin->forced_pixel_type == RL2_PIXEL_DATAGRID
1041 && origin->forced_num_bands == 1)
1042 {
1043 /* UINT16 datagrid */
1044 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1045 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
1046 return 1;
1047 if (origin->sampleFormat == SAMPLEFORMAT_INT
1048 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
1049 {
1050 origin->forced_conversion = RL2_CONVERT_GRID_INT16_TO_UINT16;
1051 return 1;
1052 }
1053 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1054 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1055 {
1056 origin->forced_conversion = RL2_CONVERT_GRID_UINT8_TO_UINT16;
1057 return 1;
1058 }
1059 if (origin->sampleFormat == SAMPLEFORMAT_INT
1060 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1061 {
1062 origin->forced_conversion = RL2_CONVERT_GRID_INT8_TO_UINT16;
1063 return 1;
1064 }
1065 if (origin->sampleFormat == SAMPLEFORMAT_INT
1066 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1067 {
1068 origin->forced_conversion = RL2_CONVERT_GRID_INT32_TO_UINT16;
1069 return 1;
1070 }
1071 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1072 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1073 {
1074 origin->forced_conversion = RL2_CONVERT_GRID_UINT32_TO_UINT16;
1075 return 1;
1076 }
1077 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1078 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1079 {
1080 origin->forced_conversion = RL2_CONVERT_GRID_FLOAT_TO_UINT16;
1081 return 1;
1082 }
1083 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1084 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 64)
1085 {
1086 origin->forced_conversion = RL2_CONVERT_GRID_DOUBLE_TO_UINT16;
1087 return 1;
1088 }
1089 }
1090 if (origin->forced_sample_type == RL2_SAMPLE_INT32
1091 && origin->forced_pixel_type == RL2_PIXEL_DATAGRID
1092 && origin->forced_num_bands == 1)
1093 {
1094 /* INT32 datagrid */
1095 if (origin->sampleFormat == SAMPLEFORMAT_INT
1096 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1097 return 1;
1098 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1099 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1100 {
1101 origin->forced_conversion = RL2_CONVERT_GRID_UINT32_TO_INT32;
1102 return 1;
1103 }
1104 if (origin->sampleFormat == SAMPLEFORMAT_INT
1105 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1106 {
1107 origin->forced_conversion = RL2_CONVERT_GRID_INT8_TO_INT32;
1108 return 1;
1109 }
1110 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1111 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1112 {
1113 origin->forced_conversion = RL2_CONVERT_GRID_UINT8_TO_INT32;
1114 return 1;
1115 }
1116 if (origin->sampleFormat == SAMPLEFORMAT_INT
1117 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
1118 {
1119 origin->forced_conversion = RL2_CONVERT_GRID_INT16_TO_INT32;
1120 return 1;
1121 }
1122 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1123 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
1124 {
1125 origin->forced_conversion = RL2_CONVERT_GRID_UINT16_TO_INT32;
1126 return 1;
1127 }
1128 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1129 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1130 {
1131 origin->forced_conversion = RL2_CONVERT_GRID_FLOAT_TO_INT32;
1132 return 1;
1133 }
1134 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1135 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 64)
1136 {
1137 origin->forced_conversion = RL2_CONVERT_GRID_DOUBLE_TO_INT32;
1138 return 1;
1139 }
1140 }
1141 if (origin->forced_sample_type == RL2_SAMPLE_UINT32
1142 && origin->forced_pixel_type == RL2_PIXEL_DATAGRID
1143 && origin->forced_num_bands == 1)
1144 {
1145 /* UINT32 datagrid */
1146 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1147 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1148 return 1;
1149 if (origin->sampleFormat == SAMPLEFORMAT_INT
1150 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1151 {
1152 origin->forced_conversion = RL2_CONVERT_GRID_INT32_TO_UINT32;
1153 return 1;
1154 }
1155 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1156 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1157 {
1158 origin->forced_conversion = RL2_CONVERT_GRID_UINT8_TO_UINT32;
1159 return 1;
1160 }
1161 if (origin->sampleFormat == SAMPLEFORMAT_INT
1162 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1163 {
1164 origin->forced_conversion = RL2_CONVERT_GRID_INT8_TO_UINT32;
1165 return 1;
1166 }
1167 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1168 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
1169 {
1170 origin->forced_conversion = RL2_CONVERT_GRID_UINT16_TO_UINT32;
1171 return 1;
1172 }
1173 if (origin->sampleFormat == SAMPLEFORMAT_INT
1174 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
1175 {
1176 origin->forced_conversion = RL2_CONVERT_GRID_INT16_TO_UINT32;
1177 return 1;
1178 }
1179 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1180 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1181 {
1182 origin->forced_conversion = RL2_CONVERT_GRID_FLOAT_TO_UINT32;
1183 return 1;
1184 }
1185 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1186 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 64)
1187 {
1188 origin->forced_conversion = RL2_CONVERT_GRID_DOUBLE_TO_UINT32;
1189 return 1;
1190 }
1191 }
1192 if (origin->forced_sample_type == RL2_SAMPLE_FLOAT
1193 && origin->forced_pixel_type == RL2_PIXEL_DATAGRID
1194 && origin->forced_num_bands == 1)
1195 {
1196 /* FLOAT datagrid */
1197 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1198 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1199 return 1;
1200 if (origin->sampleFormat == SAMPLEFORMAT_INT
1201 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1202 {
1203 origin->forced_conversion = RL2_CONVERT_GRID_INT8_TO_FLOAT;
1204 return 1;
1205 }
1206 if (origin->sampleFormat == SAMPLEFORMAT_INT
1207 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
1208 {
1209 origin->forced_conversion = RL2_CONVERT_GRID_INT16_TO_FLOAT;
1210 return 1;
1211 }
1212 if (origin->sampleFormat == SAMPLEFORMAT_INT
1213 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1214 {
1215 origin->forced_conversion = RL2_CONVERT_GRID_INT32_TO_FLOAT;
1216 return 1;
1217 }
1218 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1219 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1220 {
1221 origin->forced_conversion = RL2_CONVERT_GRID_UINT8_TO_FLOAT;
1222 return 1;
1223 }
1224 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1225 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
1226 {
1227 origin->forced_conversion = RL2_CONVERT_GRID_UINT16_TO_FLOAT;
1228 return 1;
1229 }
1230 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1231 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1232 {
1233 origin->forced_conversion = RL2_CONVERT_GRID_UINT32_TO_FLOAT;
1234 return 1;
1235 }
1236 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1237 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 64)
1238 {
1239 origin->forced_conversion = RL2_CONVERT_GRID_DOUBLE_TO_FLOAT;
1240 return 1;
1241 }
1242 }
1243 if (origin->forced_sample_type == RL2_SAMPLE_DOUBLE
1244 && origin->forced_pixel_type == RL2_PIXEL_DATAGRID
1245 && origin->forced_num_bands == 1)
1246 {
1247 /* DOUBLE datagrid */
1248 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1249 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 64)
1250 return 1;
1251 if (origin->sampleFormat == SAMPLEFORMAT_INT
1252 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1253 {
1254 origin->forced_conversion = RL2_CONVERT_GRID_INT8_TO_DOUBLE;
1255 return 1;
1256 }
1257 if (origin->sampleFormat == SAMPLEFORMAT_INT
1258 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
1259 {
1260 origin->forced_conversion = RL2_CONVERT_GRID_INT16_TO_DOUBLE;
1261 return 1;
1262 }
1263 if (origin->sampleFormat == SAMPLEFORMAT_INT
1264 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1265 {
1266 origin->forced_conversion = RL2_CONVERT_GRID_INT32_TO_DOUBLE;
1267 return 1;
1268 }
1269 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1270 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 8)
1271 {
1272 origin->forced_conversion = RL2_CONVERT_GRID_UINT8_TO_DOUBLE;
1273 return 1;
1274 }
1275 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1276 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 16)
1277 {
1278 origin->forced_conversion = RL2_CONVERT_GRID_UINT16_TO_DOUBLE;
1279 return 1;
1280 }
1281 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1282 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1283 {
1284 origin->forced_conversion = RL2_CONVERT_GRID_UINT32_TO_DOUBLE;
1285 return 1;
1286 }
1287 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP
1288 && origin->samplesPerPixel == 1 && origin->bitsPerSample == 32)
1289 {
1290 origin->forced_conversion = RL2_CONVERT_GRID_FLOAT_TO_DOUBLE;
1291 return 1;
1292 }
1293 }
1294 return 0;
1295 }
1296
1297 static int
init_tiff_origin(const char * path,rl2PrivTiffOriginPtr origin)1298 init_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin)
1299 {
1300 /* attempting to initialize a file-based TIFF origin */
1301 uint32 value32;
1302 uint16 value16;
1303
1304 /* suppressing TIFF messages */
1305 TIFFSetErrorHandler (NULL);
1306 TIFFSetWarningHandler (NULL);
1307
1308 /* reading from file */
1309 origin->in = TIFFOpen (path, "r");
1310 if (origin->in == NULL)
1311 goto error;
1312 /* tiled/striped layout */
1313 origin->isTiled = TIFFIsTiled (origin->in);
1314
1315 /* retrieving TIFF dimensions */
1316 TIFFGetField (origin->in, TIFFTAG_IMAGELENGTH, &value32);
1317 origin->height = value32;
1318 TIFFGetField (origin->in, TIFFTAG_IMAGEWIDTH, &value32);
1319 origin->width = value32;
1320 if (origin->isTiled)
1321 {
1322 TIFFGetField (origin->in, TIFFTAG_TILEWIDTH, &value32);
1323 origin->tileWidth = value32;
1324 TIFFGetField (origin->in, TIFFTAG_TILELENGTH, &value32);
1325 origin->tileHeight = value32;
1326 }
1327 else
1328 {
1329 TIFFGetField (origin->in, TIFFTAG_ROWSPERSTRIP, &value32);
1330 origin->rowsPerStrip = value32;
1331 }
1332
1333 if (origin->isGeoReferenced && origin->isGeoTiff == 0)
1334 {
1335 /* completing Worldfile georeferencing */
1336 origin->maxX =
1337 origin->minX + (origin->hResolution * (double) (origin->width));
1338 origin->minY =
1339 origin->maxY - (origin->vResolution * (double) (origin->height));
1340 }
1341
1342 /* retrieving pixel configuration */
1343 TIFFGetField (origin->in, TIFFTAG_BITSPERSAMPLE, &value16);
1344 origin->bitsPerSample = value16;
1345 if (TIFFGetField (origin->in, TIFFTAG_SAMPLESPERPIXEL, &value16) == 0)
1346 {
1347 /* attempting to recover badly formatted TIFFs */
1348 origin->samplesPerPixel = 1;
1349 }
1350 else
1351 origin->samplesPerPixel = value16;
1352 TIFFGetField (origin->in, TIFFTAG_PHOTOMETRIC, &value16);
1353 origin->photometric = value16;
1354 TIFFGetField (origin->in, TIFFTAG_COMPRESSION, &value16);
1355 origin->compression = value16;
1356 if (TIFFGetField (origin->in, TIFFTAG_SAMPLEFORMAT, &value16) == 0)
1357 origin->sampleFormat = SAMPLEFORMAT_UINT;
1358 else
1359 origin->sampleFormat = value16;
1360 if (TIFFGetField (origin->in, TIFFTAG_PLANARCONFIG, &value16) == 0)
1361 {
1362 /* attempting to recover badly formatted TIFFs */
1363 origin->planarConfig = PLANARCONFIG_CONTIG;
1364 }
1365 else
1366 origin->planarConfig = value16;
1367
1368 if (origin->bitsPerSample == 16 && origin->sampleFormat == SAMPLEFORMAT_UINT
1369 && origin->planarConfig == PLANARCONFIG_SEPARATE)
1370 ;
1371 else if (origin->bitsPerSample == 8
1372 && origin->sampleFormat == SAMPLEFORMAT_UINT
1373 && origin->planarConfig == PLANARCONFIG_SEPARATE)
1374 ;
1375 else if (origin->planarConfig != PLANARCONFIG_CONTIG)
1376 goto error;
1377
1378 if (origin->photometric == PHOTOMETRIC_PALETTE
1379 && origin->sampleFormat == SAMPLEFORMAT_UINT)
1380 {
1381 /* attempting to retrieve a Palette */
1382 uint16 *red;
1383 uint16 *green;
1384 uint16 *blue;
1385 int max_palette = 0;
1386 int i;
1387 switch (origin->bitsPerSample)
1388 {
1389 case 1:
1390 max_palette = 2;
1391 break;
1392 case 2:
1393 max_palette = 4;
1394 break;
1395 case 3:
1396 max_palette = 8;
1397 break;
1398 case 4:
1399 max_palette = 16;
1400 break;
1401 case 5:
1402 max_palette = 32;
1403 break;
1404 case 6:
1405 max_palette = 64;
1406 break;
1407 case 7:
1408 max_palette = 128;
1409 break;
1410 case 8:
1411 max_palette = 256;
1412 break;
1413 };
1414 if (origin->forced_conversion == RL2_CONVERT_GRAYSCALE_TO_PALETTE)
1415 {
1416 /* forced conversion: creating a GRAYSCALE palette */
1417 max_palette = 256;
1418 for (i = 0; i < max_palette; i++)
1419 {
1420 red[i] = i;
1421 green[i] = i;
1422 blue[i] = i;
1423 }
1424 }
1425 if (max_palette == 0)
1426 goto error;
1427 if (!alloc_palette (origin, max_palette))
1428 goto error;
1429 if (TIFFGetField (origin->in, TIFFTAG_COLORMAP, &red, &green, &blue)
1430 == 0)
1431 goto error;
1432 for (i = 0; i < max_palette; i++)
1433 {
1434 if (red[i] < 256)
1435 origin->red[i] = red[i];
1436 else
1437 origin->red[i] = red[i] / 256;
1438 if (green[i] < 256)
1439 origin->green[i] = green[i];
1440 else
1441 origin->green[i] = green[i] / 256;
1442 if (blue[i] < 256)
1443 origin->blue[i] = blue[i];
1444 else
1445 origin->blue[i] = blue[i] / 256;
1446 }
1447 if ((origin->forced_sample_type == RL2_SAMPLE_1_BIT
1448 || origin->forced_sample_type == RL2_SAMPLE_2_BIT
1449 || origin->forced_sample_type == RL2_SAMPLE_4_BIT)
1450 && origin->forced_pixel_type == RL2_PIXEL_PALETTE)
1451 {
1452 int max = 0;
1453 unsigned char plt[256];
1454 int j;
1455 unsigned char *p;
1456 unsigned short x;
1457 unsigned short y;
1458 unsigned short row;
1459 unsigned short height = 256;
1460 if (origin->isTiled)
1461 height = origin->tileHeight;
1462 for (row = 0; row < origin->height; row += height)
1463 {
1464 unsigned char *pixels = NULL;
1465 int pixels_sz = 0;
1466 rl2PalettePtr pltx = rl2_create_palette (max_palette);
1467 for (j = 0; j < max_palette; j++)
1468 rl2_set_palette_color (pltx, j, origin->red[j],
1469 origin->green[j],
1470 origin->blue[j]);
1471 if (read_from_tiff
1472 (origin, origin->width, height, RL2_SAMPLE_UINT8,
1473 RL2_PIXEL_PALETTE, 1, row, 0, &pixels, &pixels_sz,
1474 pltx) != RL2_OK)
1475 goto error;
1476 rl2_destroy_palette (pltx);
1477 p = pixels;
1478 for (y = 0; y < height; y++)
1479 {
1480 if ((y + row) >= origin->height)
1481 break;
1482 for (x = 0; x < origin->width; x++)
1483 {
1484 int ok = 0;
1485 int index = *p++;
1486 for (j = 0; j < max; j++)
1487 {
1488 if (plt[j] == index)
1489 {
1490 ok = 1;
1491 break;
1492 }
1493 }
1494 if (!ok)
1495 plt[max++] = index;
1496 }
1497 }
1498 free (pixels);
1499 }
1500 if (origin->red != NULL)
1501 free (origin->red);
1502 if (origin->green != NULL)
1503 free (origin->green);
1504 if (origin->blue != NULL)
1505 free (origin->blue);
1506 if (!alloc_palette (origin, max))
1507 goto error;
1508 for (j = 0; j < max; j++)
1509 {
1510 /* normalized palette */
1511 if (red[plt[j]] < 256)
1512 origin->red[j] = red[plt[j]];
1513 else
1514 origin->red[j] = red[plt[j]] / 256;
1515 if (green[plt[j]] < 256)
1516 origin->green[j] = green[plt[j]];
1517 else
1518 origin->green[j] = green[plt[j]] / 256;
1519 if (blue[plt[j]] < 256)
1520 origin->blue[j] = blue[plt[j]];
1521 else
1522 origin->blue[j] = blue[plt[j]] / 256;
1523 }
1524 }
1525 }
1526 if (!check_tiff_origin_pixel_conversion (origin))
1527 goto error;
1528
1529 if (origin->forced_conversion == RL2_CONVERT_GRAYSCALE_TO_PALETTE)
1530 {
1531 /* forced conversion: creating a GRAYSCALE palette */
1532 int i;
1533 if (!alloc_palette (origin, 256))
1534 goto error;
1535 for (i = 0; i < 256; i++)
1536 {
1537 origin->red[i] = i;
1538 origin->green[i] = i;
1539 origin->blue[i] = i;
1540 }
1541 }
1542 if (origin->forced_conversion == RL2_CONVERT_MONOCHROME_TO_PALETTE)
1543 {
1544 /* forced conversion: creating a BILEVEL palette */
1545 if (!alloc_palette (origin, 2))
1546 goto error;
1547 origin->red[0] = 255;
1548 origin->green[0] = 255;
1549 origin->blue[0] = 255;
1550 origin->red[1] = 0;
1551 origin->green[1] = 0;
1552 origin->blue[1] = 0;
1553 }
1554
1555 return 1;
1556 error:
1557 return 0;
1558 }
1559
1560 RL2_DECLARE rl2TiffOriginPtr
rl2_create_tiff_origin(const char * path,int georef_priority,int srid,unsigned char force_sample_type,unsigned char force_pixel_type,unsigned char force_num_bands)1561 rl2_create_tiff_origin (const char *path, int georef_priority, int srid,
1562 unsigned char force_sample_type,
1563 unsigned char force_pixel_type,
1564 unsigned char force_num_bands)
1565 {
1566 /* attempting to create a file-based TIFF / GeoTIFF origin */
1567 rl2PrivTiffOriginPtr origin = NULL;
1568
1569 if (georef_priority == RL2_TIFF_NO_GEOREF
1570 || georef_priority == RL2_TIFF_GEOTIFF
1571 || georef_priority == RL2_TIFF_WORLDFILE)
1572 ;
1573 else
1574 return NULL;
1575 origin =
1576 create_tiff_origin (path, force_sample_type, force_pixel_type,
1577 force_num_bands);
1578 if (origin == NULL)
1579 return NULL;
1580 if (georef_priority == RL2_TIFF_GEOTIFF)
1581 {
1582 /* attempting first to retrieve GeoTIFF georeferencing */
1583 geo_tiff_origin (path, origin, srid);
1584 if (origin->isGeoReferenced == 0)
1585 {
1586 /* then attempting to retrieve WorldFile georeferencing */
1587 worldfile_tiff_origin (path, origin, srid);
1588 }
1589 }
1590 else if (georef_priority == RL2_TIFF_WORLDFILE)
1591 {
1592 /* attempting first to retrieve Worldfile georeferencing */
1593 worldfile_tiff_origin (path, origin, srid);
1594 if (origin->isGeoReferenced == 0)
1595 {
1596 /* then attempting to retrieve GeoTIFF georeferencing */
1597 geo_tiff_origin (path, origin, srid);
1598 }
1599 }
1600 if (!init_tiff_origin (path, origin))
1601 goto error;
1602
1603 return (rl2TiffOriginPtr) origin;
1604 error:
1605 if (origin != NULL)
1606 rl2_destroy_tiff_origin ((rl2TiffOriginPtr) origin);
1607 return NULL;
1608 }
1609
1610 RL2_DECLARE rl2TiffOriginPtr
rl2_create_geotiff_origin(const char * path,int force_srid,unsigned char force_sample_type,unsigned char force_pixel_type,unsigned char force_num_bands)1611 rl2_create_geotiff_origin (const char *path, int force_srid,
1612 unsigned char force_sample_type,
1613 unsigned char force_pixel_type,
1614 unsigned char force_num_bands)
1615 {
1616 /* attempting to create a file-based GeoTIFF origin */
1617 rl2PrivTiffOriginPtr origin = NULL;
1618
1619 origin =
1620 create_tiff_origin (path, force_sample_type, force_pixel_type,
1621 force_num_bands);
1622 if (origin == NULL)
1623 return NULL;
1624
1625 /* attempting to retrieve GeoTIFF georeferencing */
1626 geo_tiff_origin (path, origin, force_srid);
1627 if (origin->isGeoReferenced == 0)
1628 goto error;
1629 if (!init_tiff_origin (path, origin))
1630 goto error;
1631
1632 return (rl2TiffOriginPtr) origin;
1633 error:
1634 if (origin != NULL)
1635 rl2_destroy_tiff_origin ((rl2TiffOriginPtr) origin);
1636 return NULL;
1637 }
1638
1639 RL2_DECLARE rl2TiffOriginPtr
rl2_create_tiff_worldfile_origin(const char * path,int srid,unsigned char force_sample_type,unsigned char force_pixel_type,unsigned char force_num_bands)1640 rl2_create_tiff_worldfile_origin (const char *path, int srid,
1641 unsigned char force_sample_type,
1642 unsigned char force_pixel_type,
1643 unsigned char force_num_bands)
1644 {
1645 /* attempting to create a file-based TIFF+TFW origin */
1646 rl2PrivTiffOriginPtr origin = NULL;
1647
1648 origin =
1649 create_tiff_origin (path, force_sample_type, force_pixel_type,
1650 force_num_bands);
1651 if (origin == NULL)
1652 return NULL;
1653
1654 /* attempting to retrieve Worldfile georeferencing */
1655 worldfile_tiff_origin (path, origin, srid);
1656 if (origin->isGeoReferenced == 0)
1657 goto error;
1658 if (!init_tiff_origin (path, origin))
1659 goto error;
1660
1661 return (rl2TiffOriginPtr) origin;
1662 error:
1663 if (origin != NULL)
1664 rl2_destroy_tiff_origin ((rl2TiffOriginPtr) origin);
1665 return NULL;
1666 }
1667
1668 RL2_DECLARE int
rl2_set_tiff_origin_not_referenced(rl2TiffOriginPtr tiff)1669 rl2_set_tiff_origin_not_referenced (rl2TiffOriginPtr tiff)
1670 {
1671 /* setting up a false GeoReferncing */
1672 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1673 if (origin == NULL)
1674 return RL2_ERROR;
1675 origin->hResolution = 1.0;
1676 origin->vResolution = 1.0;
1677 origin->minX = 0.0;
1678 origin->minY = 0.0;
1679 origin->maxX = origin->width - 1;
1680 origin->maxY = origin->height - 1;
1681 origin->Srid = -1;
1682 origin->isGeoReferenced = 1;
1683 origin->isGeoTiff = 0;
1684 return RL2_OK;
1685 }
1686
1687 RL2_DECLARE const char *
rl2_get_tiff_origin_path(rl2TiffOriginPtr tiff)1688 rl2_get_tiff_origin_path (rl2TiffOriginPtr tiff)
1689 {
1690 /* retrieving the input path from a TIFF origin */
1691 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1692 if (origin == NULL)
1693 return NULL;
1694
1695 return origin->path;
1696 }
1697
1698 RL2_DECLARE const char *
rl2_get_tiff_origin_worldfile_path(rl2TiffOriginPtr tiff)1699 rl2_get_tiff_origin_worldfile_path (rl2TiffOriginPtr tiff)
1700 {
1701 /* retrieving the Worldfile path from a TIFF origin */
1702 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1703 if (origin == NULL)
1704 return NULL;
1705
1706 return origin->tfw_path;
1707 }
1708
1709 RL2_DECLARE int
rl2_is_geotiff_origin(rl2TiffOriginPtr tiff,int * geotiff)1710 rl2_is_geotiff_origin (rl2TiffOriginPtr tiff, int *geotiff)
1711 {
1712 /* detecting if a TIFF origin actually is a GeoTIFF */
1713 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1714 if (origin == NULL)
1715 return RL2_ERROR;
1716 *geotiff = origin->isGeoTiff;
1717 return RL2_OK;
1718 }
1719
1720 RL2_DECLARE int
rl2_is_tiff_worldfile_origin(rl2TiffOriginPtr tiff,int * tiff_worldfile)1721 rl2_is_tiff_worldfile_origin (rl2TiffOriginPtr tiff, int *tiff_worldfile)
1722 {
1723 /* detecting if a TIFF origin actually supports a TFW */
1724 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1725 if (origin == NULL)
1726 return RL2_ERROR;
1727 *tiff_worldfile = 0;
1728 if (origin->tfw_path != NULL)
1729 *tiff_worldfile = 1;
1730 return RL2_OK;
1731 }
1732
1733 RL2_DECLARE int
rl2_get_tiff_origin_size(rl2TiffOriginPtr tiff,unsigned int * width,unsigned int * height)1734 rl2_get_tiff_origin_size (rl2TiffOriginPtr tiff, unsigned int *width,
1735 unsigned int *height)
1736 {
1737 /* retrieving Width and Height from a TIFF origin */
1738 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1739 if (origin == NULL)
1740 return RL2_ERROR;
1741
1742 *width = origin->width;
1743 *height = origin->height;
1744 return RL2_OK;
1745 }
1746
1747 RL2_DECLARE int
rl2_get_tiff_origin_srid(rl2TiffOriginPtr tiff,int * srid)1748 rl2_get_tiff_origin_srid (rl2TiffOriginPtr tiff, int *srid)
1749 {
1750 /* retrieving the SRID from a TIFF origin */
1751 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1752 if (origin == NULL)
1753 return RL2_ERROR;
1754 if (origin->isGeoReferenced == 0)
1755 return RL2_ERROR;
1756
1757 *srid = origin->Srid;
1758 return RL2_OK;
1759 }
1760
1761 RL2_DECLARE int
rl2_get_tiff_origin_extent(rl2TiffOriginPtr tiff,double * minX,double * minY,double * maxX,double * maxY)1762 rl2_get_tiff_origin_extent (rl2TiffOriginPtr tiff, double *minX, double *minY,
1763 double *maxX, double *maxY)
1764 {
1765 /* retrieving the Extent from a TIFF origin */
1766 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1767 if (origin == NULL)
1768 return RL2_ERROR;
1769 if (origin->isGeoReferenced == 0)
1770 return RL2_ERROR;
1771
1772 *minX = origin->minX;
1773 *minY = origin->minY;
1774 *maxX = origin->maxX;
1775 *maxY = origin->maxY;
1776 return RL2_OK;
1777 }
1778
1779 RL2_DECLARE int
rl2_get_tiff_origin_resolution(rl2TiffOriginPtr tiff,double * hResolution,double * vResolution)1780 rl2_get_tiff_origin_resolution (rl2TiffOriginPtr tiff, double *hResolution,
1781 double *vResolution)
1782 {
1783 /* retrieving the Pixel Resolution from a TIFF origin */
1784 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1785 if (origin == NULL)
1786 return RL2_ERROR;
1787 if (origin->isGeoReferenced == 0)
1788 return RL2_ERROR;
1789
1790 *hResolution = origin->hResolution;
1791 *vResolution = origin->vResolution;
1792 return RL2_OK;
1793 }
1794
1795 RL2_DECLARE int
rl2_get_tiff_origin_type(rl2TiffOriginPtr tiff,unsigned char * sample_type,unsigned char * pixel_type,unsigned char * alias_pixel_type,unsigned char * num_bands)1796 rl2_get_tiff_origin_type (rl2TiffOriginPtr tiff, unsigned char *sample_type,
1797 unsigned char *pixel_type,
1798 unsigned char *alias_pixel_type,
1799 unsigned char *num_bands)
1800 {
1801 /* retrieving the sample/pixel type from a TIFF origin */
1802 int ok = 0;
1803 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1804 if (origin == NULL)
1805 return RL2_ERROR;
1806
1807 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1808 && origin->samplesPerPixel == 1
1809 && origin->photometric < PHOTOMETRIC_RGB)
1810 {
1811 /* could be some kind of MONOCHROME */
1812 if (origin->bitsPerSample == 1)
1813 {
1814 *sample_type = RL2_SAMPLE_1_BIT;
1815 ok = 1;
1816 }
1817 if (ok)
1818 {
1819 *pixel_type = RL2_PIXEL_MONOCHROME;
1820 *alias_pixel_type = RL2_PIXEL_MONOCHROME;
1821 *num_bands = 1;
1822 return RL2_OK;
1823 }
1824 }
1825 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1826 && origin->samplesPerPixel == 1
1827 && origin->photometric < PHOTOMETRIC_RGB)
1828 {
1829 /* could be some kind of GRAYSCALE */
1830 if (origin->bitsPerSample == 2)
1831 {
1832 *sample_type = RL2_SAMPLE_2_BIT;
1833 ok = 1;
1834 }
1835 else if (origin->bitsPerSample == 4)
1836 {
1837 *sample_type = RL2_SAMPLE_4_BIT;
1838 ok = 1;
1839 }
1840 else if (origin->bitsPerSample == 8)
1841 {
1842 *sample_type = RL2_SAMPLE_UINT8;
1843 ok = 1;
1844 }
1845 else if (origin->bitsPerSample == 16)
1846 {
1847 *sample_type = RL2_SAMPLE_UINT16;
1848 ok = 1;
1849 }
1850 if (ok)
1851 {
1852 *pixel_type = RL2_PIXEL_GRAYSCALE;
1853 *alias_pixel_type = RL2_PIXEL_GRAYSCALE;
1854 if (origin->bitsPerSample == 8 || origin->bitsPerSample == 16)
1855 *alias_pixel_type = RL2_PIXEL_DATAGRID;
1856 *num_bands = 1;
1857 return RL2_OK;
1858 }
1859 }
1860 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1861 && origin->samplesPerPixel == 1
1862 && origin->photometric == PHOTOMETRIC_PALETTE)
1863 {
1864 /* could be some kind of PALETTE */
1865 if (origin->bitsPerSample == 1)
1866 {
1867 *sample_type = RL2_SAMPLE_1_BIT;
1868 ok = 1;
1869 }
1870 else if (origin->bitsPerSample == 2)
1871 {
1872 *sample_type = RL2_SAMPLE_2_BIT;
1873 ok = 1;
1874 }
1875 else if (origin->bitsPerSample == 4)
1876 {
1877 *sample_type = RL2_SAMPLE_4_BIT;
1878 ok = 1;
1879 }
1880 else if (origin->bitsPerSample == 8)
1881 {
1882 *sample_type = RL2_SAMPLE_UINT8;
1883 ok = 1;
1884 }
1885 if (ok)
1886 {
1887 *pixel_type = RL2_PIXEL_PALETTE;
1888 *alias_pixel_type = RL2_PIXEL_PALETTE;
1889 *num_bands = 1;
1890 return RL2_OK;
1891 }
1892 }
1893 if (origin->sampleFormat == SAMPLEFORMAT_UINT
1894 && origin->samplesPerPixel == 3
1895 && origin->photometric == PHOTOMETRIC_RGB)
1896 {
1897 /* could be some kind of RGB */
1898 if (origin->bitsPerSample == 8)
1899 {
1900 *sample_type = RL2_SAMPLE_UINT8;
1901 ok = 1;
1902 }
1903 else if (origin->bitsPerSample == 16)
1904 {
1905 *sample_type = RL2_SAMPLE_UINT16;
1906 ok = 1;
1907 }
1908 if (ok)
1909 {
1910 *pixel_type = RL2_PIXEL_RGB;
1911 *alias_pixel_type = RL2_PIXEL_RGB;
1912 *num_bands = 3;
1913 return RL2_OK;
1914 }
1915 }
1916 if (origin->samplesPerPixel == 1 && origin->photometric < PHOTOMETRIC_RGB)
1917 {
1918 /* could be some kind of DATA-GRID */
1919 if (origin->sampleFormat == SAMPLEFORMAT_INT)
1920 {
1921 /* Signed Integer */
1922 if (origin->bitsPerSample == 8)
1923 {
1924 *sample_type = RL2_SAMPLE_INT8;
1925 ok = 1;
1926 }
1927 else if (origin->bitsPerSample == 16)
1928 {
1929 *sample_type = RL2_SAMPLE_INT16;
1930 ok = 1;
1931 }
1932 else if (origin->bitsPerSample == 32)
1933 {
1934 *sample_type = RL2_SAMPLE_INT32;
1935 ok = 1;
1936 }
1937 }
1938 if (origin->sampleFormat == SAMPLEFORMAT_UINT)
1939 {
1940 /* Unsigned Integer */
1941 if (origin->bitsPerSample == 8)
1942 {
1943 *sample_type = RL2_SAMPLE_UINT8;
1944 ok = 1;
1945 }
1946 else if (origin->bitsPerSample == 16)
1947 {
1948 *sample_type = RL2_SAMPLE_UINT16;
1949 ok = 1;
1950 }
1951 else if (origin->bitsPerSample == 32)
1952 {
1953 *sample_type = RL2_SAMPLE_UINT32;
1954 ok = 1;
1955 }
1956 }
1957 if (origin->sampleFormat == SAMPLEFORMAT_IEEEFP)
1958 {
1959 /* Floating-Point */
1960 if (origin->bitsPerSample == 32)
1961 {
1962 *sample_type = RL2_SAMPLE_FLOAT;
1963 ok = 1;
1964 }
1965 else if (origin->bitsPerSample == 64)
1966 {
1967 *sample_type = RL2_SAMPLE_DOUBLE;
1968 ok = 1;
1969 }
1970 }
1971 if (ok)
1972 {
1973 *pixel_type = RL2_PIXEL_DATAGRID;
1974 *alias_pixel_type = RL2_PIXEL_DATAGRID;
1975 *num_bands = 1;
1976 return RL2_OK;
1977 }
1978 }
1979 return RL2_ERROR;
1980 }
1981
1982 RL2_DECLARE int
rl2_get_tiff_origin_forced_type(rl2TiffOriginPtr tiff,unsigned char * sample_type,unsigned char * pixel_type,unsigned char * num_bands)1983 rl2_get_tiff_origin_forced_type (rl2TiffOriginPtr tiff,
1984 unsigned char *sample_type,
1985 unsigned char *pixel_type,
1986 unsigned char *num_bands)
1987 {
1988 /* retrieving the sample/pixel type (FORCED) from a TIFF origin */
1989 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
1990 if (origin == NULL)
1991 return RL2_ERROR;
1992
1993 *sample_type = origin->forced_sample_type;
1994 *pixel_type = origin->forced_pixel_type;
1995 *num_bands = origin->forced_num_bands;
1996 return RL2_OK;
1997 }
1998
1999 RL2_DECLARE int
rl2_get_tiff_origin_compression(rl2TiffOriginPtr tiff,unsigned char * compression)2000 rl2_get_tiff_origin_compression (rl2TiffOriginPtr tiff,
2001 unsigned char *compression)
2002 {
2003 /* retrieving the sample/pixel type from a TIFF origin */
2004 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
2005 if (origin == NULL)
2006 return RL2_ERROR;
2007
2008 switch (origin->compression)
2009 {
2010 case COMPRESSION_NONE:
2011 *compression = RL2_COMPRESSION_NONE;
2012 break;
2013 case COMPRESSION_LZW:
2014 *compression = RL2_COMPRESSION_LZW;
2015 break;
2016 case COMPRESSION_DEFLATE:
2017 *compression = RL2_COMPRESSION_DEFLATE;
2018 break;
2019 case COMPRESSION_LZMA:
2020 *compression = RL2_COMPRESSION_LZMA;
2021 break;
2022 case COMPRESSION_JPEG:
2023 *compression = RL2_COMPRESSION_JPEG;
2024 break;
2025 case COMPRESSION_CCITTFAX3:
2026 *compression = RL2_COMPRESSION_CCITTFAX3;
2027 break;
2028 case COMPRESSION_CCITTFAX4:
2029 *compression = RL2_COMPRESSION_CCITTFAX4;
2030 break;
2031 default:
2032 *compression = RL2_COMPRESSION_UNKNOWN;
2033 break;
2034 }
2035 return RL2_OK;
2036 }
2037
2038 RL2_DECLARE int
rl2_eval_tiff_origin_compatibility(rl2CoveragePtr cvg,rl2TiffOriginPtr tiff,int force_srid)2039 rl2_eval_tiff_origin_compatibility (rl2CoveragePtr cvg, rl2TiffOriginPtr tiff,
2040 int force_srid)
2041 {
2042 /* testing if a Coverage and a TIFF origin are mutually compatible */
2043 unsigned char sample_type;
2044 unsigned char pixel_type;
2045 unsigned char num_bands;
2046 int srid;
2047 double hResolution;
2048 double vResolution;
2049 double confidence;
2050 rl2PrivCoveragePtr coverage = (rl2PrivCoveragePtr) cvg;
2051
2052 if (coverage == NULL || tiff == NULL)
2053 return RL2_ERROR;
2054 if (rl2_get_tiff_origin_forced_type
2055 (tiff, &sample_type, &pixel_type, &num_bands) != RL2_OK)
2056 return RL2_ERROR;
2057
2058 /* aliasing GRAYSCALE and DATAGRID for UINT8 */
2059 if (coverage->sampleType == RL2_SAMPLE_UINT8
2060 && coverage->pixelType == RL2_PIXEL_DATAGRID
2061 && pixel_type == RL2_PIXEL_GRAYSCALE)
2062 pixel_type = RL2_PIXEL_DATAGRID;
2063 /* aliasing GRAYSCALE and DATAGRID for UINT16 */
2064 if (coverage->sampleType == RL2_SAMPLE_UINT16
2065 && coverage->pixelType == RL2_PIXEL_DATAGRID
2066 && pixel_type == RL2_PIXEL_GRAYSCALE)
2067 pixel_type = RL2_PIXEL_DATAGRID;
2068
2069 if (coverage->sampleType != sample_type)
2070 return RL2_FALSE;
2071 if (coverage->pixelType != pixel_type)
2072 return RL2_FALSE;
2073 if (coverage->nBands != num_bands)
2074 return RL2_FALSE;
2075
2076 if (coverage->Srid == RL2_GEOREFERENCING_NONE)
2077 return RL2_TRUE;
2078
2079 /* checking for resolution compatibility */
2080 if (rl2_get_tiff_origin_srid (tiff, &srid) != RL2_OK)
2081 return RL2_FALSE;
2082 if (coverage->Srid != srid)
2083 {
2084 if (force_srid > 0)
2085 {
2086 if (coverage->Srid != force_srid)
2087 return RL2_FALSE;
2088 }
2089 else
2090 return RL2_FALSE;
2091 }
2092 if (rl2_get_tiff_origin_resolution (tiff, &hResolution, &vResolution) !=
2093 RL2_OK)
2094 return RL2_FALSE;
2095 confidence = coverage->hResolution / 100.0;
2096 if (hResolution < (coverage->hResolution - confidence)
2097 || hResolution > (coverage->hResolution + confidence))
2098 return RL2_FALSE;
2099 confidence = coverage->vResolution / 100.0;
2100 if (vResolution < (coverage->vResolution - confidence)
2101 || vResolution > (coverage->vResolution + confidence))
2102 return RL2_FALSE;
2103 return RL2_TRUE;
2104 }
2105
2106 RL2_PRIVATE char
truncate_8(double val)2107 truncate_8 (double val)
2108 {
2109 /* truncating to signed 8 bit integer */
2110 if (val <= INT8_MIN)
2111 return INT8_MIN;
2112 if (val >= INT8_MAX)
2113 return INT8_MAX;
2114 return (char) val;
2115 }
2116
2117 RL2_PRIVATE unsigned char
truncate_u8(double val)2118 truncate_u8 (double val)
2119 {
2120 /* truncating to unsigned 8 bit integer */
2121 if (val <= 0.0)
2122 return 0;
2123 if (val >= UINT8_MAX)
2124 return UINT8_MAX;
2125 return (unsigned char) val;
2126 }
2127
2128 RL2_PRIVATE short
truncate_16(double val)2129 truncate_16 (double val)
2130 {
2131 /* truncating to signed 16 bit integer */
2132 if (val <= INT16_MIN)
2133 return INT16_MIN;
2134 if (val >= INT16_MAX)
2135 return INT16_MAX;
2136 return (short) val;
2137 }
2138
2139 RL2_PRIVATE unsigned short
truncate_u16(double val)2140 truncate_u16 (double val)
2141 {
2142 /* truncating to unsigned 16 bit integer */
2143 if (val <= 0.0)
2144 return 0;
2145 if (val >= UINT16_MAX)
2146 return UINT16_MAX;
2147 return (unsigned short) val;
2148 }
2149
2150 RL2_PRIVATE int
truncate_32(double val)2151 truncate_32 (double val)
2152 {
2153 /* truncating to signed 32 bit integer */
2154 if (val <= INT32_MIN)
2155 return INT32_MIN;
2156 if (val >= INT32_MAX)
2157 return INT32_MAX;
2158 return (int) val;
2159 }
2160
2161 RL2_PRIVATE unsigned int
truncate_u32(double val)2162 truncate_u32 (double val)
2163 {
2164 /* truncating to unsigned 32 bit integer */
2165 if (val <= 0.0)
2166 return 0;
2167 if (val >= UINT32_MAX)
2168 return UINT32_MAX;
2169 return (unsigned int) val;
2170 }
2171
2172 static void
copy_convert_tile(rl2PrivTiffOriginPtr origin,void * in,void * out,unsigned int startRow,unsigned int startCol,unsigned short width,unsigned short height,uint32 tile_y,uint32 tile_x,unsigned char convert)2173 copy_convert_tile (rl2PrivTiffOriginPtr origin, void *in, void *out,
2174 unsigned int startRow, unsigned int startCol,
2175 unsigned short width, unsigned short height, uint32 tile_y,
2176 uint32 tile_x, unsigned char convert)
2177 {
2178 /* copying pixels by applying a format conversion */
2179 char *p_in_8;
2180 char *p_out_8;
2181 unsigned char *p_in_u8;
2182 unsigned char *p_out_u8;
2183 short *p_in_16;
2184 short *p_out_16;
2185 unsigned short *p_in_u16;
2186 unsigned short *p_out_u16;
2187 int *p_in_32;
2188 int *p_out_32;
2189 unsigned int *p_in_u32;
2190 unsigned int *p_out_u32;
2191 float *p_in_flt;
2192 float *p_out_flt;
2193 double *p_in_dbl;
2194 double *p_out_dbl;
2195 uint32 x;
2196 uint32 y;
2197 unsigned int dest_x;
2198 unsigned int dest_y;
2199
2200 for (y = 0; y < origin->tileHeight; y++)
2201 {
2202 dest_y = tile_y + y;
2203 if (dest_y < startRow || dest_y >= (startRow + height))
2204 continue;
2205
2206 switch (convert)
2207 {
2208 case RL2_CONVERT_GRID_INT8_TO_UINT8:
2209 case RL2_CONVERT_GRID_INT8_TO_INT16:
2210 case RL2_CONVERT_GRID_INT8_TO_UINT16:
2211 case RL2_CONVERT_GRID_INT8_TO_INT32:
2212 case RL2_CONVERT_GRID_INT8_TO_UINT32:
2213 case RL2_CONVERT_GRID_INT8_TO_FLOAT:
2214 case RL2_CONVERT_GRID_INT8_TO_DOUBLE:
2215 p_in_8 = (char *) in;
2216 p_in_8 += y * origin->tileWidth;
2217 break;
2218 case RL2_CONVERT_GRID_UINT8_TO_INT8:
2219 case RL2_CONVERT_GRID_UINT8_TO_UINT16:
2220 case RL2_CONVERT_GRID_UINT8_TO_INT16:
2221 case RL2_CONVERT_GRID_UINT8_TO_UINT32:
2222 case RL2_CONVERT_GRID_UINT8_TO_INT32:
2223 case RL2_CONVERT_GRID_UINT8_TO_FLOAT:
2224 case RL2_CONVERT_GRID_UINT8_TO_DOUBLE:
2225 p_in_u8 = (unsigned char *) in;
2226 p_in_u8 += y * origin->tileWidth;
2227 break;
2228 case RL2_CONVERT_GRID_INT16_TO_INT8:
2229 case RL2_CONVERT_GRID_INT16_TO_UINT8:
2230 case RL2_CONVERT_GRID_INT16_TO_UINT16:
2231 case RL2_CONVERT_GRID_INT16_TO_INT32:
2232 case RL2_CONVERT_GRID_INT16_TO_UINT32:
2233 case RL2_CONVERT_GRID_INT16_TO_FLOAT:
2234 case RL2_CONVERT_GRID_INT16_TO_DOUBLE:
2235 p_in_16 = (short *) in;
2236 p_in_16 += y * origin->tileWidth;
2237 break;
2238 case RL2_CONVERT_GRID_UINT16_TO_INT8:
2239 case RL2_CONVERT_GRID_UINT16_TO_UINT8:
2240 case RL2_CONVERT_GRID_UINT16_TO_INT16:
2241 case RL2_CONVERT_GRID_UINT16_TO_UINT32:
2242 case RL2_CONVERT_GRID_UINT16_TO_INT32:
2243 case RL2_CONVERT_GRID_UINT16_TO_FLOAT:
2244 case RL2_CONVERT_GRID_UINT16_TO_DOUBLE:
2245 p_in_u16 = (unsigned short *) in;
2246 p_in_u16 += y * origin->tileWidth;
2247 break;
2248 case RL2_CONVERT_GRID_INT32_TO_INT8:
2249 case RL2_CONVERT_GRID_INT32_TO_UINT8:
2250 case RL2_CONVERT_GRID_INT32_TO_INT16:
2251 case RL2_CONVERT_GRID_INT32_TO_UINT16:
2252 case RL2_CONVERT_GRID_INT32_TO_UINT32:
2253 case RL2_CONVERT_GRID_INT32_TO_FLOAT:
2254 case RL2_CONVERT_GRID_INT32_TO_DOUBLE:
2255 p_in_32 = (int *) in;
2256 p_in_32 += y * origin->tileWidth;
2257 break;
2258 case RL2_CONVERT_GRID_UINT32_TO_INT8:
2259 case RL2_CONVERT_GRID_UINT32_TO_UINT8:
2260 case RL2_CONVERT_GRID_UINT32_TO_INT16:
2261 case RL2_CONVERT_GRID_UINT32_TO_UINT16:
2262 case RL2_CONVERT_GRID_UINT32_TO_INT32:
2263 case RL2_CONVERT_GRID_UINT32_TO_FLOAT:
2264 case RL2_CONVERT_GRID_UINT32_TO_DOUBLE:
2265 p_in_u32 = (unsigned int *) in;
2266 p_in_u32 += y * origin->tileWidth;
2267 break;
2268 case RL2_CONVERT_GRID_FLOAT_TO_INT8:
2269 case RL2_CONVERT_GRID_FLOAT_TO_UINT8:
2270 case RL2_CONVERT_GRID_FLOAT_TO_INT16:
2271 case RL2_CONVERT_GRID_FLOAT_TO_UINT16:
2272 case RL2_CONVERT_GRID_FLOAT_TO_INT32:
2273 case RL2_CONVERT_GRID_FLOAT_TO_UINT32:
2274 case RL2_CONVERT_GRID_FLOAT_TO_DOUBLE:
2275 p_in_flt = (float *) in;
2276 p_in_flt += y * origin->tileWidth;
2277 break;
2278 case RL2_CONVERT_GRID_DOUBLE_TO_INT8:
2279 case RL2_CONVERT_GRID_DOUBLE_TO_UINT8:
2280 case RL2_CONVERT_GRID_DOUBLE_TO_INT16:
2281 case RL2_CONVERT_GRID_DOUBLE_TO_UINT16:
2282 case RL2_CONVERT_GRID_DOUBLE_TO_INT32:
2283 case RL2_CONVERT_GRID_DOUBLE_TO_UINT32:
2284 case RL2_CONVERT_GRID_DOUBLE_TO_FLOAT:
2285 p_in_dbl = (double *) in;
2286 p_in_dbl += y * origin->tileWidth;
2287 break;
2288 };
2289
2290 for (x = 0; x < origin->tileWidth; x++)
2291 {
2292 dest_x = tile_x + x;
2293 if (dest_x < startCol || dest_x >= (startCol + width))
2294 continue;
2295
2296 switch (convert)
2297 {
2298 case RL2_CONVERT_GRID_UINT8_TO_INT8:
2299 case RL2_CONVERT_GRID_INT16_TO_INT8:
2300 case RL2_CONVERT_GRID_UINT16_TO_INT8:
2301 case RL2_CONVERT_GRID_INT32_TO_INT8:
2302 case RL2_CONVERT_GRID_UINT32_TO_INT8:
2303 case RL2_CONVERT_GRID_FLOAT_TO_INT8:
2304 case RL2_CONVERT_GRID_DOUBLE_TO_INT8:
2305 p_out_8 = (char *) out;
2306 p_out_8 +=
2307 ((dest_y - startRow) * width) + (dest_x - startCol);
2308 break;
2309 case RL2_CONVERT_GRID_INT8_TO_UINT8:
2310 case RL2_CONVERT_GRID_INT16_TO_UINT8:
2311 case RL2_CONVERT_GRID_UINT16_TO_UINT8:
2312 case RL2_CONVERT_GRID_INT32_TO_UINT8:
2313 case RL2_CONVERT_GRID_UINT32_TO_UINT8:
2314 case RL2_CONVERT_GRID_FLOAT_TO_UINT8:
2315 case RL2_CONVERT_GRID_DOUBLE_TO_UINT8:
2316 p_out_u8 = (unsigned char *) out;
2317 p_out_u8 +=
2318 ((dest_y - startRow) * width) + (dest_x - startCol);
2319 break;
2320 case RL2_CONVERT_GRID_INT8_TO_INT16:
2321 case RL2_CONVERT_GRID_UINT8_TO_INT16:
2322 case RL2_CONVERT_GRID_UINT16_TO_INT16:
2323 case RL2_CONVERT_GRID_INT32_TO_INT16:
2324 case RL2_CONVERT_GRID_UINT32_TO_INT16:
2325 case RL2_CONVERT_GRID_FLOAT_TO_INT16:
2326 case RL2_CONVERT_GRID_DOUBLE_TO_INT16:
2327 p_out_16 = (short *) out;
2328 p_out_16 +=
2329 ((dest_y - startRow) * width) + (dest_x - startCol);
2330 break;
2331 case RL2_CONVERT_GRID_INT8_TO_UINT16:
2332 case RL2_CONVERT_GRID_UINT8_TO_UINT16:
2333 case RL2_CONVERT_GRID_INT16_TO_UINT16:
2334 case RL2_CONVERT_GRID_INT32_TO_UINT16:
2335 case RL2_CONVERT_GRID_UINT32_TO_UINT16:
2336 case RL2_CONVERT_GRID_FLOAT_TO_UINT16:
2337 case RL2_CONVERT_GRID_DOUBLE_TO_UINT16:
2338 p_out_u16 = (unsigned short *) out;
2339 p_out_u16 +=
2340 ((dest_y - startRow) * width) + (dest_x - startCol);
2341 break;
2342 case RL2_CONVERT_GRID_INT8_TO_INT32:
2343 case RL2_CONVERT_GRID_UINT8_TO_INT32:
2344 case RL2_CONVERT_GRID_INT16_TO_INT32:
2345 case RL2_CONVERT_GRID_UINT16_TO_INT32:
2346 case RL2_CONVERT_GRID_UINT32_TO_INT32:
2347 case RL2_CONVERT_GRID_FLOAT_TO_INT32:
2348 case RL2_CONVERT_GRID_DOUBLE_TO_INT32:
2349 p_out_32 = (int *) out;
2350 p_out_32 +=
2351 ((dest_y - startRow) * width) + (dest_x - startCol);
2352 break;
2353 case RL2_CONVERT_GRID_INT8_TO_UINT32:
2354 case RL2_CONVERT_GRID_UINT8_TO_UINT32:
2355 case RL2_CONVERT_GRID_INT16_TO_UINT32:
2356 case RL2_CONVERT_GRID_UINT16_TO_UINT32:
2357 case RL2_CONVERT_GRID_INT32_TO_UINT32:
2358 case RL2_CONVERT_GRID_FLOAT_TO_UINT32:
2359 case RL2_CONVERT_GRID_DOUBLE_TO_UINT32:
2360 p_out_u32 = (unsigned int *) out;
2361 p_out_u32 +=
2362 ((dest_y - startRow) * width) + (dest_x - startCol);
2363 break;
2364 case RL2_CONVERT_GRID_INT8_TO_FLOAT:
2365 case RL2_CONVERT_GRID_UINT8_TO_FLOAT:
2366 case RL2_CONVERT_GRID_INT16_TO_FLOAT:
2367 case RL2_CONVERT_GRID_UINT16_TO_FLOAT:
2368 case RL2_CONVERT_GRID_INT32_TO_FLOAT:
2369 case RL2_CONVERT_GRID_UINT32_TO_FLOAT:
2370 case RL2_CONVERT_GRID_DOUBLE_TO_FLOAT:
2371 p_out_flt = (float *) out;
2372 p_out_flt +=
2373 ((dest_y - startRow) * width) + (dest_x - startCol);
2374 break;
2375 case RL2_CONVERT_GRID_INT8_TO_DOUBLE:
2376 case RL2_CONVERT_GRID_UINT8_TO_DOUBLE:
2377 case RL2_CONVERT_GRID_INT16_TO_DOUBLE:
2378 case RL2_CONVERT_GRID_UINT16_TO_DOUBLE:
2379 case RL2_CONVERT_GRID_INT32_TO_DOUBLE:
2380 case RL2_CONVERT_GRID_UINT32_TO_DOUBLE:
2381 case RL2_CONVERT_GRID_FLOAT_TO_DOUBLE:
2382 p_out_dbl = (double *) out;
2383 p_out_dbl +=
2384 ((dest_y - startRow) * width) + (dest_x - startCol);
2385 break;
2386 };
2387
2388 switch (convert)
2389 {
2390 case RL2_CONVERT_GRID_INT8_TO_UINT8:
2391 *p_out_u8++ = truncate_u8 (*p_in_8++);
2392 break;
2393 case RL2_CONVERT_GRID_INT8_TO_INT16:
2394 *p_out_16++ = *p_in_8++;
2395 break;
2396 case RL2_CONVERT_GRID_INT8_TO_UINT16:
2397 *p_out_u16++ = truncate_u16 (*p_in_8++);
2398 break;
2399 case RL2_CONVERT_GRID_INT8_TO_INT32:
2400 *p_out_32++ = *p_in_8++;
2401 break;
2402 case RL2_CONVERT_GRID_INT8_TO_UINT32:
2403 *p_out_u32++ = truncate_u32 (*p_in_8++);
2404 break;
2405 case RL2_CONVERT_GRID_INT8_TO_FLOAT:
2406 *p_out_flt++ = *p_in_8++;
2407 break;
2408 case RL2_CONVERT_GRID_INT8_TO_DOUBLE:
2409 *p_out_dbl++ = *p_in_8++;
2410 break;
2411 case RL2_CONVERT_GRID_UINT8_TO_INT8:
2412 *p_out_8++ = truncate_8 (*p_in_u8++);
2413 break;
2414 case RL2_CONVERT_GRID_UINT8_TO_INT16:
2415 *p_out_16++ = truncate_16 (*p_in_u8++);
2416 break;
2417 case RL2_CONVERT_GRID_UINT8_TO_UINT16:
2418 *p_out_u16++ = *p_in_u8++;
2419 break;
2420 case RL2_CONVERT_GRID_UINT8_TO_UINT32:
2421 *p_out_u32++ = *p_in_u8++;
2422 break;
2423 case RL2_CONVERT_GRID_UINT8_TO_INT32:
2424 *p_out_32++ = truncate_32 (*p_in_u8++);
2425 break;
2426 case RL2_CONVERT_GRID_UINT8_TO_FLOAT:
2427 *p_out_flt++ = *p_in_u8++;
2428 break;
2429 case RL2_CONVERT_GRID_UINT8_TO_DOUBLE:
2430 *p_out_dbl++ = *p_in_u8++;
2431 break;
2432 case RL2_CONVERT_GRID_INT16_TO_INT8:
2433 *p_out_8++ = truncate_8 (*p_in_16++);
2434 break;
2435 case RL2_CONVERT_GRID_INT16_TO_UINT8:
2436 *p_out_u8++ = truncate_u8 (*p_in_16++);
2437 break;
2438 case RL2_CONVERT_GRID_INT16_TO_UINT16:
2439 *p_out_u16++ = truncate_u16 (*p_in_16++);
2440 break;
2441 case RL2_CONVERT_GRID_INT16_TO_INT32:
2442 *p_out_32++ = *p_in_16++;
2443 break;
2444 case RL2_CONVERT_GRID_INT16_TO_UINT32:
2445 *p_out_u32++ = truncate_u32 (*p_in_16++);
2446 break;
2447 case RL2_CONVERT_GRID_INT16_TO_FLOAT:
2448 *p_out_flt++ = *p_in_16++;
2449 break;
2450 case RL2_CONVERT_GRID_INT16_TO_DOUBLE:
2451 *p_out_dbl++ = *p_in_16++;
2452 break;
2453 case RL2_CONVERT_GRID_UINT16_TO_INT8:
2454 *p_out_8++ = truncate_8 (*p_in_u16++);
2455 break;
2456 case RL2_CONVERT_GRID_UINT16_TO_UINT8:
2457 *p_out_u8++ = truncate_u8 (*p_in_u16++);
2458 break;
2459 case RL2_CONVERT_GRID_UINT16_TO_INT16:
2460 *p_out_16++ = truncate_16 (*p_in_u16++);
2461 break;
2462 case RL2_CONVERT_GRID_UINT16_TO_UINT32:
2463 *p_out_u32++ = *p_in_u16++;
2464 break;
2465 case RL2_CONVERT_GRID_UINT16_TO_INT32:
2466 *p_out_32++ = truncate_32 (*p_in_u16++);
2467 break;
2468 case RL2_CONVERT_GRID_UINT16_TO_FLOAT:
2469 *p_out_flt++ = *p_in_u16++;
2470 break;
2471 case RL2_CONVERT_GRID_UINT16_TO_DOUBLE:
2472 *p_out_dbl++ = *p_in_u16++;
2473 break;
2474 case RL2_CONVERT_GRID_INT32_TO_INT8:
2475 *p_out_8++ = truncate_8 (*p_in_32++);
2476 break;
2477 case RL2_CONVERT_GRID_INT32_TO_UINT8:
2478 *p_out_u8++ = truncate_u8 (*p_in_32++);
2479 break;
2480 case RL2_CONVERT_GRID_INT32_TO_INT16:
2481 *p_out_16++ = truncate_16 (*p_in_32++);
2482 break;
2483 case RL2_CONVERT_GRID_INT32_TO_UINT16:
2484 *p_out_u16++ = truncate_u16 (*p_in_32++);
2485 break;
2486 case RL2_CONVERT_GRID_INT32_TO_UINT32:
2487 *p_out_u32++ = truncate_u32 (*p_in_32++);
2488 break;
2489 case RL2_CONVERT_GRID_INT32_TO_FLOAT:
2490 *p_out_flt++ = *p_in_32++;
2491 break;
2492 case RL2_CONVERT_GRID_INT32_TO_DOUBLE:
2493 *p_out_dbl++ = *p_in_32++;
2494 break;
2495 case RL2_CONVERT_GRID_UINT32_TO_INT8:
2496 *p_out_8++ = truncate_8 (*p_in_u32++);
2497 break;
2498 case RL2_CONVERT_GRID_UINT32_TO_UINT8:
2499 *p_out_u8++ = truncate_u8 (*p_in_u32++);
2500 break;
2501 case RL2_CONVERT_GRID_UINT32_TO_INT16:
2502 *p_out_16++ = truncate_16 (*p_in_u32++);
2503 break;
2504 case RL2_CONVERT_GRID_UINT32_TO_UINT16:
2505 *p_out_u16++ = truncate_u16 (*p_in_u32++);
2506 break;
2507 case RL2_CONVERT_GRID_UINT32_TO_INT32:
2508 *p_out_32++ = truncate_32 (*p_in_u32++);
2509 break;
2510 case RL2_CONVERT_GRID_UINT32_TO_FLOAT:
2511 *p_out_flt++ = *p_in_u32++;
2512 break;
2513 case RL2_CONVERT_GRID_UINT32_TO_DOUBLE:
2514 *p_out_dbl++ = *p_in_u32++;
2515 break;
2516 case RL2_CONVERT_GRID_FLOAT_TO_INT8:
2517 *p_out_8++ = truncate_8 (*p_in_flt++);
2518 break;
2519 case RL2_CONVERT_GRID_FLOAT_TO_UINT8:
2520 *p_out_u8++ = truncate_u8 (*p_in_flt++);
2521 break;
2522 case RL2_CONVERT_GRID_FLOAT_TO_INT16:
2523 *p_out_16++ = truncate_16 (*p_in_flt++);
2524 break;
2525 case RL2_CONVERT_GRID_FLOAT_TO_UINT16:
2526 *p_out_u16++ = truncate_u16 (*p_in_flt++);
2527 break;
2528 case RL2_CONVERT_GRID_FLOAT_TO_INT32:
2529 *p_out_32++ = truncate_32 (*p_in_flt++);
2530 break;
2531 case RL2_CONVERT_GRID_FLOAT_TO_UINT32:
2532 *p_out_u32++ = truncate_u32 (*p_in_flt++);
2533 break;
2534 case RL2_CONVERT_GRID_FLOAT_TO_DOUBLE:
2535 *p_out_dbl++ = *p_in_flt++;
2536 break;
2537 case RL2_CONVERT_GRID_DOUBLE_TO_INT8:
2538 *p_out_8++ = truncate_8 (*p_in_dbl++);
2539 break;
2540 case RL2_CONVERT_GRID_DOUBLE_TO_UINT8:
2541 *p_out_u8++ = truncate_u8 (*p_in_dbl++);
2542 break;
2543 case RL2_CONVERT_GRID_DOUBLE_TO_INT16:
2544 *p_out_16++ = truncate_16 (*p_in_dbl++);
2545 break;
2546 case RL2_CONVERT_GRID_DOUBLE_TO_UINT16:
2547 *p_out_u16++ = truncate_u16 (*p_in_dbl++);
2548 break;
2549 case RL2_CONVERT_GRID_DOUBLE_TO_INT32:
2550 *p_out_32++ = truncate_32 (*p_in_dbl++);
2551 break;
2552 case RL2_CONVERT_GRID_DOUBLE_TO_UINT32:
2553 *p_out_u32++ = truncate_u32 (*p_in_dbl++);
2554 break;
2555 case RL2_CONVERT_GRID_DOUBLE_TO_FLOAT:
2556 *p_out_flt++ = *p_in_dbl++;
2557 break;
2558 };
2559 }
2560 }
2561 }
2562
2563 static int
read_raw_tiles(rl2PrivTiffOriginPtr origin,unsigned short width,unsigned short height,unsigned char sample_type,unsigned char num_bands,unsigned int startRow,unsigned int startCol,unsigned char * pixels)2564 read_raw_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
2565 unsigned short height, unsigned char sample_type,
2566 unsigned char num_bands, unsigned int startRow,
2567 unsigned int startCol, unsigned char *pixels)
2568 {
2569 /* reading TIFF raw tiles */
2570 uint32 tile_x;
2571 uint32 tile_y;
2572 uint32 x;
2573 uint32 y;
2574 uint32 *tiff_tile = NULL;
2575 char *p_in_8;
2576 char *p_out_8;
2577 unsigned char *p_in_u8;
2578 unsigned char *p_out_u8;
2579 short *p_in_16;
2580 short *p_out_16;
2581 unsigned short *p_in_u16;
2582 unsigned short *p_out_u16;
2583 int *p_in_32;
2584 int *p_out_32;
2585 unsigned int *p_in_u32;
2586 unsigned int *p_out_u32;
2587 float *p_in_flt;
2588 float *p_out_flt;
2589 double *p_in_dbl;
2590 double *p_out_dbl;
2591 unsigned int dest_x;
2592 unsigned int dest_y;
2593 int skip;
2594 unsigned char bnd;
2595 unsigned char convert = origin->forced_conversion;
2596
2597 tiff_tile = malloc (TIFFTileSize (origin->in));
2598 if (tiff_tile == NULL)
2599 goto error;
2600
2601 for (tile_y = 0; tile_y < origin->height; tile_y += origin->tileHeight)
2602 {
2603 /* scanning tiles by row */
2604 unsigned int tiff_min_y = tile_y;
2605 unsigned int tiff_max_y = tile_y + origin->tileHeight - 1;
2606 skip = 0;
2607 if (tiff_min_y > (startRow + height))
2608 skip = 1;
2609 if (tiff_max_y < startRow)
2610 skip = 1;
2611 if (skip)
2612 {
2613 /* skipping any not required tile */
2614 continue;
2615 }
2616 for (tile_x = 0; tile_x < origin->width; tile_x += origin->tileWidth)
2617 {
2618 /* reading a TIFF tile */
2619 unsigned int tiff_min_x = tile_x;
2620 unsigned int tiff_max_x = tile_x + origin->tileWidth - 1;
2621 skip = 0;
2622 if (tiff_min_x > (startCol + width))
2623 skip = 1;
2624 if (tiff_max_x < startCol)
2625 skip = 1;
2626 if (skip)
2627 {
2628 /* skipping any not required tile */
2629 continue;
2630 }
2631 if (TIFFReadTile (origin->in, tiff_tile, tile_x, tile_y, 0, 0) <
2632 0)
2633 goto error;
2634 if (convert != RL2_CONVERT_NO)
2635 {
2636 /* applying some format conversion */
2637 copy_convert_tile (origin, tiff_tile, pixels, startRow,
2638 startCol, width, height, tile_y,
2639 tile_x, convert);
2640 continue;
2641 }
2642 for (y = 0; y < origin->tileHeight; y++)
2643 {
2644 dest_y = tile_y + y;
2645 if (dest_y < startRow || dest_y >= (startRow + height))
2646 continue;
2647 for (x = 0; x < origin->tileWidth; x++)
2648 {
2649 dest_x = tile_x + x;
2650 if (dest_x < startCol
2651 || dest_x >= (startCol + width))
2652 continue;
2653 switch (sample_type)
2654 {
2655 case RL2_SAMPLE_INT8:
2656 p_in_8 = (char *) tiff_tile;
2657 p_in_8 += y * origin->tileWidth;
2658 p_in_8 += x;
2659 p_out_8 = (char *) pixels;
2660 p_out_8 +=
2661 ((dest_y - startRow) * width) + (dest_x -
2662 startCol);
2663 break;
2664 case RL2_SAMPLE_UINT8:
2665 p_in_u8 = (unsigned char *) tiff_tile;
2666 p_in_u8 += y * origin->tileWidth * num_bands;
2667 p_in_u8 += x * num_bands;
2668 p_out_u8 = (unsigned char *) pixels;
2669 p_out_u8 +=
2670 ((dest_y -
2671 startRow) * width * num_bands) +
2672 ((dest_x - startCol) * num_bands);
2673 break;
2674 case RL2_SAMPLE_INT16:
2675 p_in_16 = (short *) tiff_tile;
2676 p_in_16 += y * origin->tileWidth;
2677 p_in_16 += x;
2678 p_out_16 = (short *) pixels;
2679 p_out_16 +=
2680 ((dest_y - startRow) * width) + (dest_x -
2681 startCol);
2682 break;
2683 case RL2_SAMPLE_UINT16:
2684 p_in_u16 = (unsigned short *) tiff_tile;
2685 p_in_u16 += y * origin->tileWidth * num_bands;
2686 p_in_u16 += x * num_bands;
2687 p_out_u16 = (unsigned short *) pixels;
2688 p_out_u16 +=
2689 ((dest_y -
2690 startRow) * width * num_bands) +
2691 ((dest_x - startCol) * num_bands);
2692 break;
2693 case RL2_SAMPLE_INT32:
2694 p_in_32 = (int *) tiff_tile;
2695 p_in_32 += y * origin->tileWidth;
2696 p_in_32 += x;
2697 p_out_32 = (int *) pixels;
2698 p_out_32 +=
2699 ((dest_y - startRow) * width) + (dest_x -
2700 startCol);
2701 break;
2702 case RL2_SAMPLE_UINT32:
2703 p_in_u32 = (unsigned int *) tiff_tile;
2704 p_in_u32 += y * origin->tileWidth;
2705 p_in_u32 += x;
2706 p_out_u32 = (unsigned int *) pixels;
2707 p_out_u32 +=
2708 ((dest_y - startRow) * width) + (dest_x -
2709 startCol);
2710 break;
2711 case RL2_SAMPLE_FLOAT:
2712 p_in_flt = (float *) tiff_tile;
2713 p_in_flt += y * origin->tileWidth;
2714 p_in_flt += x;
2715 p_out_flt = (float *) pixels;
2716 p_out_flt +=
2717 ((dest_y - startRow) * width) + (dest_x -
2718 startCol);
2719 break;
2720 case RL2_SAMPLE_DOUBLE:
2721 p_in_dbl = (double *) tiff_tile;
2722 p_in_dbl += y * origin->tileWidth;
2723 p_in_dbl += x;
2724 p_out_dbl = (double *) pixels;
2725 p_out_dbl +=
2726 ((dest_y - startRow) * width) + (dest_x -
2727 startCol);
2728 break;
2729 };
2730 for (bnd = 0; bnd < num_bands; bnd++)
2731 {
2732 switch (sample_type)
2733 {
2734 case RL2_SAMPLE_INT8:
2735 *p_out_8 = *p_in_8++;
2736 break;
2737 case RL2_SAMPLE_UINT8:
2738 *p_out_u8 = *p_in_u8++;
2739 break;
2740 case RL2_SAMPLE_INT16:
2741 *p_out_16 = *p_in_16++;
2742 break;
2743 case RL2_SAMPLE_UINT16:
2744 *p_out_u16 = *p_in_u16++;
2745 break;
2746 case RL2_SAMPLE_INT32:
2747 *p_out_32 = *p_in_32++;
2748 break;
2749 case RL2_SAMPLE_UINT32:
2750 *p_out_u32 = *p_in_u32++;
2751 break;
2752 case RL2_SAMPLE_FLOAT:
2753 *p_out_flt = *p_in_flt++;
2754 break;
2755 case RL2_SAMPLE_DOUBLE:
2756 *p_out_dbl = *p_in_dbl++;
2757 break;
2758 };
2759 }
2760 }
2761 }
2762 }
2763 }
2764
2765 free (tiff_tile);
2766 return RL2_OK;
2767 error:
2768 if (tiff_tile != NULL)
2769 free (tiff_tile);
2770 return RL2_ERROR;
2771 }
2772
2773 static void
copy_convert_scanline(rl2PrivTiffOriginPtr origin,void * in,void * out,unsigned int lineNo,unsigned int startCol,unsigned int width,unsigned char convert)2774 copy_convert_scanline (rl2PrivTiffOriginPtr origin, void *in, void *out,
2775 unsigned int lineNo, unsigned int startCol,
2776 unsigned int width, unsigned char convert)
2777 {
2778 /* copying pixels by applying a format conversion */
2779 char *p_in_8;
2780 char *p_out_8;
2781 unsigned char *p_in_u8;
2782 unsigned char *p_out_u8;
2783 short *p_in_16;
2784 short *p_out_16;
2785 unsigned short *p_in_u16;
2786 unsigned short *p_out_u16;
2787 int *p_in_32;
2788 int *p_out_32;
2789 unsigned int *p_in_u32;
2790 unsigned int *p_out_u32;
2791 float *p_in_flt;
2792 float *p_out_flt;
2793 double *p_in_dbl;
2794 double *p_out_dbl;
2795 uint32 x;
2796
2797 switch (convert)
2798 {
2799 case RL2_CONVERT_GRID_INT8_TO_UINT8:
2800 case RL2_CONVERT_GRID_INT8_TO_INT16:
2801 case RL2_CONVERT_GRID_INT8_TO_UINT16:
2802 case RL2_CONVERT_GRID_INT8_TO_INT32:
2803 case RL2_CONVERT_GRID_INT8_TO_UINT32:
2804 case RL2_CONVERT_GRID_INT8_TO_FLOAT:
2805 case RL2_CONVERT_GRID_INT8_TO_DOUBLE:
2806 p_in_8 = (char *) in;
2807 break;
2808 case RL2_CONVERT_GRID_UINT8_TO_INT8:
2809 case RL2_CONVERT_GRID_UINT8_TO_UINT16:
2810 case RL2_CONVERT_GRID_UINT8_TO_INT16:
2811 case RL2_CONVERT_GRID_UINT8_TO_UINT32:
2812 case RL2_CONVERT_GRID_UINT8_TO_INT32:
2813 case RL2_CONVERT_GRID_UINT8_TO_FLOAT:
2814 case RL2_CONVERT_GRID_UINT8_TO_DOUBLE:
2815 p_in_u8 = (unsigned char *) in;
2816 break;
2817 case RL2_CONVERT_GRID_INT16_TO_INT8:
2818 case RL2_CONVERT_GRID_INT16_TO_UINT8:
2819 case RL2_CONVERT_GRID_INT16_TO_UINT16:
2820 case RL2_CONVERT_GRID_INT16_TO_INT32:
2821 case RL2_CONVERT_GRID_INT16_TO_UINT32:
2822 case RL2_CONVERT_GRID_INT16_TO_FLOAT:
2823 case RL2_CONVERT_GRID_INT16_TO_DOUBLE:
2824 p_in_16 = (short *) in;
2825 break;
2826 case RL2_CONVERT_GRID_UINT16_TO_INT8:
2827 case RL2_CONVERT_GRID_UINT16_TO_UINT8:
2828 case RL2_CONVERT_GRID_UINT16_TO_INT16:
2829 case RL2_CONVERT_GRID_UINT16_TO_UINT32:
2830 case RL2_CONVERT_GRID_UINT16_TO_INT32:
2831 case RL2_CONVERT_GRID_UINT16_TO_FLOAT:
2832 case RL2_CONVERT_GRID_UINT16_TO_DOUBLE:
2833 p_in_u16 = (unsigned short *) in;
2834 break;
2835 case RL2_CONVERT_GRID_INT32_TO_INT8:
2836 case RL2_CONVERT_GRID_INT32_TO_UINT8:
2837 case RL2_CONVERT_GRID_INT32_TO_INT16:
2838 case RL2_CONVERT_GRID_INT32_TO_UINT16:
2839 case RL2_CONVERT_GRID_INT32_TO_UINT32:
2840 case RL2_CONVERT_GRID_INT32_TO_FLOAT:
2841 case RL2_CONVERT_GRID_INT32_TO_DOUBLE:
2842 p_in_32 = (int *) in;
2843 break;
2844 case RL2_CONVERT_GRID_UINT32_TO_INT8:
2845 case RL2_CONVERT_GRID_UINT32_TO_UINT8:
2846 case RL2_CONVERT_GRID_UINT32_TO_INT16:
2847 case RL2_CONVERT_GRID_UINT32_TO_UINT16:
2848 case RL2_CONVERT_GRID_UINT32_TO_INT32:
2849 case RL2_CONVERT_GRID_UINT32_TO_FLOAT:
2850 case RL2_CONVERT_GRID_UINT32_TO_DOUBLE:
2851 p_in_u32 = (unsigned int *) in;
2852 break;
2853 case RL2_CONVERT_GRID_FLOAT_TO_INT8:
2854 case RL2_CONVERT_GRID_FLOAT_TO_UINT8:
2855 case RL2_CONVERT_GRID_FLOAT_TO_INT16:
2856 case RL2_CONVERT_GRID_FLOAT_TO_UINT16:
2857 case RL2_CONVERT_GRID_FLOAT_TO_INT32:
2858 case RL2_CONVERT_GRID_FLOAT_TO_UINT32:
2859 case RL2_CONVERT_GRID_FLOAT_TO_DOUBLE:
2860 p_in_flt = (float *) in;
2861 break;
2862 case RL2_CONVERT_GRID_DOUBLE_TO_INT8:
2863 case RL2_CONVERT_GRID_DOUBLE_TO_UINT8:
2864 case RL2_CONVERT_GRID_DOUBLE_TO_INT16:
2865 case RL2_CONVERT_GRID_DOUBLE_TO_UINT16:
2866 case RL2_CONVERT_GRID_DOUBLE_TO_INT32:
2867 case RL2_CONVERT_GRID_DOUBLE_TO_UINT32:
2868 case RL2_CONVERT_GRID_DOUBLE_TO_FLOAT:
2869 p_in_dbl = (double *) in;
2870 break;
2871 };
2872
2873 switch (convert)
2874 {
2875 case RL2_CONVERT_GRID_UINT8_TO_INT8:
2876 case RL2_CONVERT_GRID_INT16_TO_INT8:
2877 case RL2_CONVERT_GRID_UINT16_TO_INT8:
2878 case RL2_CONVERT_GRID_INT32_TO_INT8:
2879 case RL2_CONVERT_GRID_UINT32_TO_INT8:
2880 case RL2_CONVERT_GRID_FLOAT_TO_INT8:
2881 case RL2_CONVERT_GRID_DOUBLE_TO_INT8:
2882 p_out_8 = (char *) out;
2883 p_out_8 += lineNo * width;
2884 break;
2885 case RL2_CONVERT_GRID_INT8_TO_UINT8:
2886 case RL2_CONVERT_GRID_INT16_TO_UINT8:
2887 case RL2_CONVERT_GRID_UINT16_TO_UINT8:
2888 case RL2_CONVERT_GRID_INT32_TO_UINT8:
2889 case RL2_CONVERT_GRID_UINT32_TO_UINT8:
2890 case RL2_CONVERT_GRID_FLOAT_TO_UINT8:
2891 case RL2_CONVERT_GRID_DOUBLE_TO_UINT8:
2892 p_out_u8 = (unsigned char *) out;
2893 p_out_u8 += lineNo * width;
2894 break;
2895 case RL2_CONVERT_GRID_INT8_TO_INT16:
2896 case RL2_CONVERT_GRID_UINT8_TO_INT16:
2897 case RL2_CONVERT_GRID_UINT16_TO_INT16:
2898 case RL2_CONVERT_GRID_INT32_TO_INT16:
2899 case RL2_CONVERT_GRID_UINT32_TO_INT16:
2900 case RL2_CONVERT_GRID_FLOAT_TO_INT16:
2901 case RL2_CONVERT_GRID_DOUBLE_TO_INT16:
2902 p_out_16 = (short *) out;
2903 p_out_16 += lineNo * width;
2904 break;
2905 case RL2_CONVERT_GRID_INT8_TO_UINT16:
2906 case RL2_CONVERT_GRID_UINT8_TO_UINT16:
2907 case RL2_CONVERT_GRID_INT16_TO_UINT16:
2908 case RL2_CONVERT_GRID_INT32_TO_UINT16:
2909 case RL2_CONVERT_GRID_UINT32_TO_UINT16:
2910 case RL2_CONVERT_GRID_FLOAT_TO_UINT16:
2911 case RL2_CONVERT_GRID_DOUBLE_TO_UINT16:
2912 p_out_u16 = (unsigned short *) out;
2913 p_out_u16 += lineNo * width;
2914 break;
2915 case RL2_CONVERT_GRID_INT8_TO_INT32:
2916 case RL2_CONVERT_GRID_UINT8_TO_INT32:
2917 case RL2_CONVERT_GRID_INT16_TO_INT32:
2918 case RL2_CONVERT_GRID_UINT16_TO_INT32:
2919 case RL2_CONVERT_GRID_UINT32_TO_INT32:
2920 case RL2_CONVERT_GRID_FLOAT_TO_INT32:
2921 case RL2_CONVERT_GRID_DOUBLE_TO_INT32:
2922 p_out_32 = (int *) out;
2923 p_out_32 += lineNo * width;
2924 break;
2925 case RL2_CONVERT_GRID_INT8_TO_UINT32:
2926 case RL2_CONVERT_GRID_UINT8_TO_UINT32:
2927 case RL2_CONVERT_GRID_INT16_TO_UINT32:
2928 case RL2_CONVERT_GRID_UINT16_TO_UINT32:
2929 case RL2_CONVERT_GRID_INT32_TO_UINT32:
2930 case RL2_CONVERT_GRID_FLOAT_TO_UINT32:
2931 case RL2_CONVERT_GRID_DOUBLE_TO_UINT32:
2932 p_out_u32 = (unsigned int *) out;
2933 p_out_u32 += lineNo * width;
2934 break;
2935 case RL2_CONVERT_GRID_INT8_TO_FLOAT:
2936 case RL2_CONVERT_GRID_UINT8_TO_FLOAT:
2937 case RL2_CONVERT_GRID_INT16_TO_FLOAT:
2938 case RL2_CONVERT_GRID_UINT16_TO_FLOAT:
2939 case RL2_CONVERT_GRID_INT32_TO_FLOAT:
2940 case RL2_CONVERT_GRID_UINT32_TO_FLOAT:
2941 case RL2_CONVERT_GRID_DOUBLE_TO_FLOAT:
2942 p_out_flt = (float *) out;
2943 p_out_flt += lineNo * width;
2944 break;
2945 case RL2_CONVERT_GRID_INT8_TO_DOUBLE:
2946 case RL2_CONVERT_GRID_UINT8_TO_DOUBLE:
2947 case RL2_CONVERT_GRID_INT16_TO_DOUBLE:
2948 case RL2_CONVERT_GRID_UINT16_TO_DOUBLE:
2949 case RL2_CONVERT_GRID_INT32_TO_DOUBLE:
2950 case RL2_CONVERT_GRID_UINT32_TO_DOUBLE:
2951 case RL2_CONVERT_GRID_FLOAT_TO_DOUBLE:
2952 p_out_dbl = (double *) out;
2953 p_out_dbl += lineNo * width;
2954 break;
2955 };
2956
2957 for (x = 0; x < origin->width; x++)
2958 {
2959 if (x >= (startCol + width))
2960 break;
2961 if (x < startCol)
2962 {
2963 switch (convert)
2964 {
2965 case RL2_CONVERT_GRID_INT8_TO_UINT8:
2966 case RL2_CONVERT_GRID_INT8_TO_INT16:
2967 case RL2_CONVERT_GRID_INT8_TO_UINT16:
2968 case RL2_CONVERT_GRID_INT8_TO_INT32:
2969 case RL2_CONVERT_GRID_INT8_TO_UINT32:
2970 case RL2_CONVERT_GRID_INT8_TO_FLOAT:
2971 case RL2_CONVERT_GRID_INT8_TO_DOUBLE:
2972 p_in_8++;
2973 break;
2974 case RL2_CONVERT_GRID_UINT8_TO_INT8:
2975 case RL2_CONVERT_GRID_UINT8_TO_INT16:
2976 case RL2_CONVERT_GRID_UINT8_TO_UINT16:
2977 case RL2_CONVERT_GRID_UINT8_TO_INT32:
2978 case RL2_CONVERT_GRID_UINT8_TO_UINT32:
2979 case RL2_CONVERT_GRID_UINT8_TO_FLOAT:
2980 case RL2_CONVERT_GRID_UINT8_TO_DOUBLE:
2981 p_in_u8++;
2982 break;
2983 case RL2_CONVERT_GRID_INT16_TO_INT8:
2984 case RL2_CONVERT_GRID_INT16_TO_UINT8:
2985 case RL2_CONVERT_GRID_INT16_TO_UINT16:
2986 case RL2_CONVERT_GRID_INT16_TO_INT32:
2987 case RL2_CONVERT_GRID_INT16_TO_UINT32:
2988 case RL2_CONVERT_GRID_INT16_TO_FLOAT:
2989 case RL2_CONVERT_GRID_INT16_TO_DOUBLE:
2990 p_in_16++;
2991 break;
2992 case RL2_CONVERT_GRID_UINT16_TO_INT8:
2993 case RL2_CONVERT_GRID_UINT16_TO_UINT8:
2994 case RL2_CONVERT_GRID_UINT16_TO_INT16:
2995 case RL2_CONVERT_GRID_UINT16_TO_INT32:
2996 case RL2_CONVERT_GRID_UINT16_TO_UINT32:
2997 case RL2_CONVERT_GRID_UINT16_TO_FLOAT:
2998 case RL2_CONVERT_GRID_UINT16_TO_DOUBLE:
2999 p_in_u16++;
3000 break;
3001 case RL2_CONVERT_GRID_INT32_TO_INT8:
3002 case RL2_CONVERT_GRID_INT32_TO_UINT8:
3003 case RL2_CONVERT_GRID_INT32_TO_INT16:
3004 case RL2_CONVERT_GRID_INT32_TO_UINT16:
3005 case RL2_CONVERT_GRID_INT32_TO_UINT32:
3006 case RL2_CONVERT_GRID_INT32_TO_FLOAT:
3007 case RL2_CONVERT_GRID_INT32_TO_DOUBLE:
3008 p_in_32++;
3009 break;
3010 case RL2_CONVERT_GRID_UINT32_TO_INT8:
3011 case RL2_CONVERT_GRID_UINT32_TO_UINT8:
3012 case RL2_CONVERT_GRID_UINT32_TO_INT16:
3013 case RL2_CONVERT_GRID_UINT32_TO_UINT16:
3014 case RL2_CONVERT_GRID_UINT32_TO_INT32:
3015 case RL2_CONVERT_GRID_UINT32_TO_FLOAT:
3016 case RL2_CONVERT_GRID_UINT32_TO_DOUBLE:
3017 p_in_u32++;
3018 break;
3019 case RL2_CONVERT_GRID_FLOAT_TO_INT8:
3020 case RL2_CONVERT_GRID_FLOAT_TO_UINT8:
3021 case RL2_CONVERT_GRID_FLOAT_TO_INT16:
3022 case RL2_CONVERT_GRID_FLOAT_TO_UINT16:
3023 case RL2_CONVERT_GRID_FLOAT_TO_INT32:
3024 case RL2_CONVERT_GRID_FLOAT_TO_UINT32:
3025 case RL2_CONVERT_GRID_FLOAT_TO_DOUBLE:
3026 p_in_flt++;
3027 break;
3028 case RL2_CONVERT_GRID_DOUBLE_TO_INT8:
3029 case RL2_CONVERT_GRID_DOUBLE_TO_UINT8:
3030 case RL2_CONVERT_GRID_DOUBLE_TO_INT16:
3031 case RL2_CONVERT_GRID_DOUBLE_TO_UINT16:
3032 case RL2_CONVERT_GRID_DOUBLE_TO_INT32:
3033 case RL2_CONVERT_GRID_DOUBLE_TO_UINT32:
3034 case RL2_CONVERT_GRID_DOUBLE_TO_FLOAT:
3035 p_in_dbl++;
3036 break;
3037 };
3038 continue;
3039 }
3040
3041 switch (convert)
3042 {
3043 case RL2_CONVERT_GRID_INT8_TO_UINT8:
3044 *p_out_u8++ = truncate_u8 (*p_in_8++);
3045 break;
3046 case RL2_CONVERT_GRID_INT8_TO_INT16:
3047 *p_out_16++ = *p_in_8++;
3048 break;
3049 case RL2_CONVERT_GRID_INT8_TO_UINT16:
3050 *p_out_u16++ = truncate_u16 (*p_in_8++);
3051 break;
3052 case RL2_CONVERT_GRID_INT8_TO_INT32:
3053 *p_out_32++ = *p_in_8++;
3054 break;
3055 case RL2_CONVERT_GRID_INT8_TO_UINT32:
3056 *p_out_u32++ = truncate_u32 (*p_in_8++);
3057 break;
3058 case RL2_CONVERT_GRID_INT8_TO_FLOAT:
3059 *p_out_flt++ = *p_in_8++;
3060 break;
3061 case RL2_CONVERT_GRID_INT8_TO_DOUBLE:
3062 *p_out_dbl++ = *p_in_8++;
3063 break;
3064 case RL2_CONVERT_GRID_UINT8_TO_INT8:
3065 *p_out_8++ = truncate_8 (*p_in_u8++);
3066 break;
3067 case RL2_CONVERT_GRID_UINT8_TO_INT16:
3068 *p_out_16++ = truncate_16 (*p_in_u8++);
3069 break;
3070 case RL2_CONVERT_GRID_UINT8_TO_UINT16:
3071 *p_out_u16++ = *p_in_u8++;
3072 break;
3073 case RL2_CONVERT_GRID_UINT8_TO_UINT32:
3074 *p_out_u32++ = *p_in_u8++;
3075 break;
3076 case RL2_CONVERT_GRID_UINT8_TO_INT32:
3077 *p_out_32++ = truncate_32 (*p_in_u8++);
3078 break;
3079 case RL2_CONVERT_GRID_UINT8_TO_FLOAT:
3080 *p_out_flt++ = *p_in_u8++;
3081 break;
3082 case RL2_CONVERT_GRID_UINT8_TO_DOUBLE:
3083 *p_out_dbl++ = *p_in_u8++;
3084 break;
3085 case RL2_CONVERT_GRID_INT16_TO_INT8:
3086 *p_out_8++ = truncate_8 (*p_in_16++);
3087 break;
3088 case RL2_CONVERT_GRID_INT16_TO_UINT8:
3089 *p_out_u8++ = truncate_u8 (*p_in_16++);
3090 break;
3091 case RL2_CONVERT_GRID_INT16_TO_UINT16:
3092 *p_out_u16++ = truncate_u16 (*p_in_16++);
3093 break;
3094 case RL2_CONVERT_GRID_INT16_TO_INT32:
3095 *p_out_32++ = *p_in_16++;
3096 break;
3097 case RL2_CONVERT_GRID_INT16_TO_UINT32:
3098 *p_out_u32++ = truncate_u32 (*p_in_16++);
3099 break;
3100 case RL2_CONVERT_GRID_INT16_TO_FLOAT:
3101 *p_out_flt++ = *p_in_16++;
3102 break;
3103 case RL2_CONVERT_GRID_INT16_TO_DOUBLE:
3104 *p_out_dbl++ = *p_in_16++;
3105 break;
3106 case RL2_CONVERT_GRID_UINT16_TO_INT8:
3107 *p_out_8++ = truncate_8 (*p_in_u16++);
3108 break;
3109 case RL2_CONVERT_GRID_UINT16_TO_UINT8:
3110 *p_out_u8++ = truncate_u8 (*p_in_u16++);
3111 break;
3112 case RL2_CONVERT_GRID_UINT16_TO_INT16:
3113 *p_out_16++ = truncate_16 (*p_in_u16++);
3114 break;
3115 case RL2_CONVERT_GRID_UINT16_TO_UINT32:
3116 *p_out_u32++ = *p_in_u16++;
3117 break;
3118 case RL2_CONVERT_GRID_UINT16_TO_INT32:
3119 *p_out_32++ = truncate_32 (*p_in_u16++);
3120 break;
3121 case RL2_CONVERT_GRID_UINT16_TO_FLOAT:
3122 *p_out_flt++ = *p_in_u16++;
3123 break;
3124 case RL2_CONVERT_GRID_UINT16_TO_DOUBLE:
3125 *p_out_dbl++ = *p_in_u16++;
3126 break;
3127 case RL2_CONVERT_GRID_INT32_TO_INT8:
3128 *p_out_8++ = truncate_8 (*p_in_32++);
3129 break;
3130 case RL2_CONVERT_GRID_INT32_TO_UINT8:
3131 *p_out_u8++ = truncate_u8 (*p_in_32++);
3132 break;
3133 case RL2_CONVERT_GRID_INT32_TO_INT16:
3134 *p_out_16++ = truncate_16 (*p_in_32++);
3135 break;
3136 case RL2_CONVERT_GRID_INT32_TO_UINT16:
3137 *p_out_u16++ = truncate_u16 (*p_in_32++);
3138 break;
3139 case RL2_CONVERT_GRID_INT32_TO_UINT32:
3140 *p_out_u32++ = truncate_u32 (*p_in_32++);
3141 break;
3142 case RL2_CONVERT_GRID_INT32_TO_FLOAT:
3143 *p_out_flt++ = *p_in_32++;
3144 break;
3145 case RL2_CONVERT_GRID_INT32_TO_DOUBLE:
3146 *p_out_dbl++ = *p_in_32++;
3147 break;
3148 case RL2_CONVERT_GRID_UINT32_TO_INT8:
3149 *p_out_8++ = truncate_8 (*p_in_u32++);
3150 break;
3151 case RL2_CONVERT_GRID_UINT32_TO_UINT8:
3152 *p_out_u8++ = truncate_u8 (*p_in_u32++);
3153 break;
3154 case RL2_CONVERT_GRID_UINT32_TO_INT16:
3155 *p_out_16++ = truncate_16 (*p_in_u32++);
3156 break;
3157 case RL2_CONVERT_GRID_UINT32_TO_UINT16:
3158 *p_out_u16++ = truncate_u16 (*p_in_u32++);
3159 break;
3160 case RL2_CONVERT_GRID_UINT32_TO_INT32:
3161 *p_out_32++ = truncate_32 (*p_in_u32++);
3162 break;
3163 case RL2_CONVERT_GRID_UINT32_TO_FLOAT:
3164 *p_out_flt++ = *p_in_u32++;
3165 break;
3166 case RL2_CONVERT_GRID_UINT32_TO_DOUBLE:
3167 *p_out_dbl++ = *p_in_u32++;
3168 break;
3169 case RL2_CONVERT_GRID_FLOAT_TO_INT8:
3170 *p_out_8++ = truncate_8 (*p_in_flt++);
3171 break;
3172 case RL2_CONVERT_GRID_FLOAT_TO_UINT8:
3173 *p_out_u8++ = truncate_u8 (*p_in_flt++);
3174 break;
3175 case RL2_CONVERT_GRID_FLOAT_TO_INT16:
3176 *p_out_16++ = truncate_16 (*p_in_flt++);
3177 break;
3178 case RL2_CONVERT_GRID_FLOAT_TO_UINT16:
3179 *p_out_u16++ = truncate_u16 (*p_in_flt++);
3180 break;
3181 case RL2_CONVERT_GRID_FLOAT_TO_INT32:
3182 *p_out_32++ = truncate_32 (*p_in_flt++);
3183 break;
3184 case RL2_CONVERT_GRID_FLOAT_TO_UINT32:
3185 *p_out_u32++ = truncate_u32 (*p_in_flt++);
3186 break;
3187 case RL2_CONVERT_GRID_FLOAT_TO_DOUBLE:
3188 *p_out_dbl++ = *p_in_flt++;
3189 break;
3190 case RL2_CONVERT_GRID_DOUBLE_TO_INT8:
3191 *p_out_8++ = truncate_8 (*p_in_dbl++);
3192 break;
3193 case RL2_CONVERT_GRID_DOUBLE_TO_UINT8:
3194 *p_out_u8++ = truncate_u8 (*p_in_dbl++);
3195 break;
3196 case RL2_CONVERT_GRID_DOUBLE_TO_INT16:
3197 *p_out_16++ = truncate_16 (*p_in_dbl++);
3198 break;
3199 case RL2_CONVERT_GRID_DOUBLE_TO_UINT16:
3200 *p_out_u16++ = truncate_u16 (*p_in_dbl++);
3201 break;
3202 case RL2_CONVERT_GRID_DOUBLE_TO_INT32:
3203 *p_out_32++ = truncate_32 (*p_in_dbl++);
3204 break;
3205 case RL2_CONVERT_GRID_DOUBLE_TO_UINT32:
3206 *p_out_u32++ = truncate_u32 (*p_in_dbl++);
3207 break;
3208 case RL2_CONVERT_GRID_DOUBLE_TO_FLOAT:
3209 *p_out_flt++ = *p_in_dbl++;
3210 break;
3211 };
3212 }
3213 }
3214
3215 static int
read_raw_scanlines(rl2PrivTiffOriginPtr origin,unsigned short width,unsigned short height,unsigned char sample_type,unsigned char num_bands,unsigned int startRow,unsigned int startCol,unsigned char * pixels)3216 read_raw_scanlines (rl2PrivTiffOriginPtr origin, unsigned short width,
3217 unsigned short height, unsigned char sample_type,
3218 unsigned char num_bands, unsigned int startRow,
3219 unsigned int startCol, unsigned char *pixels)
3220 {
3221 /* reading TIFF raw strips */
3222 uint32 line_no;
3223 uint32 x;
3224 uint32 y;
3225 uint32 *tiff_scanline = NULL;
3226 char *p_in_8;
3227 char *p_out_8;
3228 unsigned char *p_in_u8;
3229 unsigned char *p_out_u8;
3230 short *p_in_16;
3231 short *p_out_16;
3232 unsigned short *p_in_u16;
3233 unsigned short *p_out_u16;
3234 int *p_in_32;
3235 int *p_out_32;
3236 unsigned int *p_in_u32;
3237 unsigned int *p_out_u32;
3238 float *p_in_flt;
3239 float *p_out_flt;
3240 double *p_in_dbl;
3241 double *p_out_dbl;
3242 unsigned char bnd;
3243 unsigned char convert = origin->forced_conversion;
3244 TIFF *in = (TIFF *) 0;
3245
3246 tiff_scanline = malloc (TIFFScanlineSize (origin->in));
3247 if (tiff_scanline == NULL)
3248 goto error;
3249
3250 /*
3251 / random access doesn't work on compressed scanlines
3252 / so we'll open an auxiliary TIFF handle, thus ensuring
3253 / an always clean reading context
3254 */
3255 in = TIFFOpen (origin->path, "r");
3256 if (in == NULL)
3257 goto error;
3258
3259 for (y = 0; y < startRow; y++)
3260 {
3261 /* skipping trailing scanlines */
3262 if (TIFFReadScanline (in, tiff_scanline, y, 0) < 0)
3263 goto error;
3264 }
3265
3266 for (y = 0; y < height; y++)
3267 {
3268 /* scanning scanlines by row */
3269 line_no = y + startRow;
3270 if (line_no >= origin->height)
3271 {
3272 switch (sample_type)
3273 {
3274 case RL2_SAMPLE_INT8:
3275 p_out_8 = (char *) pixels;
3276 for (x = 0; x < width; x++)
3277 *p_out_8++ = 0;
3278 break;
3279 case RL2_SAMPLE_UINT8:
3280 p_out_u8 = (unsigned char *) pixels;
3281 for (x = 0; x < width * num_bands; x++)
3282 *p_out_u8++ = 0;
3283 break;
3284 case RL2_SAMPLE_INT16:
3285 p_out_16 = (short *) pixels;
3286 for (x = 0; x < width; x++)
3287 *p_out_16++ = 0;
3288 break;
3289 case RL2_SAMPLE_UINT16:
3290 p_out_u16 = (unsigned short *) pixels;
3291 for (x = 0; x < width * num_bands; x++)
3292 *p_out_u16++ = 0;
3293 break;
3294 case RL2_SAMPLE_INT32:
3295 p_out_32 = (int *) pixels;
3296 for (x = 0; x < width; x++)
3297 *p_out_32++ = 0;
3298 break;
3299 case RL2_SAMPLE_UINT32:
3300 p_out_u32 = (unsigned int *) pixels;
3301 for (x = 0; x < width; x++)
3302 *p_out_u32++ = 0;
3303 break;
3304 case RL2_SAMPLE_FLOAT:
3305 p_out_flt = (float *) pixels;
3306 for (x = 0; x < width; x++)
3307 *p_out_flt++ = 0;
3308 break;
3309 case RL2_SAMPLE_DOUBLE:
3310 p_out_dbl = (double *) pixels;
3311 for (x = 0; x < width; x++)
3312 *p_out_dbl++ = 0;
3313 break;
3314 default:
3315 goto error;
3316 };
3317 continue;
3318 }
3319 if (TIFFReadScanline (in, tiff_scanline, line_no, 0) < 0)
3320 goto error;
3321 if (convert != RL2_CONVERT_NO)
3322 {
3323 /* applying some format conversion */
3324 copy_convert_scanline (origin, tiff_scanline, pixels, y,
3325 startCol, width, convert);
3326 continue;
3327 }
3328 switch (sample_type)
3329 {
3330 case RL2_SAMPLE_INT8:
3331 p_in_8 = (char *) tiff_scanline;
3332 p_out_8 = (char *) pixels;
3333 p_out_8 += y * width;
3334 break;
3335 case RL2_SAMPLE_UINT8:
3336 p_in_u8 = (unsigned char *) tiff_scanline;
3337 p_out_u8 = (unsigned char *) pixels;
3338 p_out_u8 += y * width * num_bands;
3339 break;
3340 case RL2_SAMPLE_INT16:
3341 p_in_16 = (short *) tiff_scanline;
3342 p_out_16 = (short *) pixels;
3343 p_out_16 += y * width;
3344 break;
3345 case RL2_SAMPLE_UINT16:
3346 p_in_u16 = (unsigned short *) tiff_scanline;
3347 p_out_u16 = (unsigned short *) pixels;
3348 p_out_u16 += y * width * num_bands;
3349 break;
3350 case RL2_SAMPLE_INT32:
3351 p_in_32 = (int *) tiff_scanline;
3352 p_out_32 = (int *) pixels;
3353 p_out_32 += y * width;
3354 break;
3355 case RL2_SAMPLE_UINT32:
3356 p_in_u32 = (unsigned int *) tiff_scanline;
3357 p_out_u32 = (unsigned int *) pixels;
3358 p_out_u32 += y * width;
3359 break;
3360 case RL2_SAMPLE_FLOAT:
3361 p_in_flt = (float *) tiff_scanline;
3362 p_out_flt = (float *) pixels;
3363 p_out_flt += y * width;
3364 break;
3365 case RL2_SAMPLE_DOUBLE:
3366 p_in_dbl = (double *) tiff_scanline;
3367 p_out_dbl = (double *) pixels;
3368 p_out_dbl += y * width;
3369 break;
3370 default:
3371 goto error;
3372 };
3373 for (x = 0; x < origin->width; x++)
3374 {
3375 if (x >= (startCol + width))
3376 break;
3377 if (x < startCol)
3378 {
3379 for (bnd = 0; bnd < num_bands; bnd++)
3380 {
3381 switch (sample_type)
3382 {
3383 case RL2_SAMPLE_INT8:
3384 p_in_8++;
3385 break;
3386 case RL2_SAMPLE_UINT8:
3387 p_in_u8++;
3388 break;
3389 case RL2_SAMPLE_INT16:
3390 p_in_16++;
3391 break;
3392 case RL2_SAMPLE_UINT16:
3393 p_in_u16++;
3394 break;
3395 case RL2_SAMPLE_INT32:
3396 p_in_32++;
3397 break;
3398 case RL2_SAMPLE_UINT32:
3399 p_in_u32++;
3400 break;
3401 case RL2_SAMPLE_FLOAT:
3402 p_in_flt++;
3403 break;
3404 case RL2_SAMPLE_DOUBLE:
3405 p_in_dbl++;
3406 break;
3407 };
3408 }
3409 continue;
3410 }
3411 for (bnd = 0; bnd < num_bands; bnd++)
3412 {
3413 switch (sample_type)
3414 {
3415 case RL2_SAMPLE_INT8:
3416 *p_out_8++ = *p_in_8++;
3417 break;
3418 case RL2_SAMPLE_UINT8:
3419 *p_out_u8++ = *p_in_u8++;
3420 break;
3421 case RL2_SAMPLE_INT16:
3422 *p_out_16++ = *p_in_16++;
3423 break;
3424 case RL2_SAMPLE_UINT16:
3425 *p_out_u16++ = *p_in_u16++;
3426 break;
3427 case RL2_SAMPLE_INT32:
3428 *p_out_32++ = *p_in_32++;
3429 break;
3430 case RL2_SAMPLE_UINT32:
3431 *p_out_u32++ = *p_in_u32++;
3432 break;
3433 case RL2_SAMPLE_FLOAT:
3434 *p_out_flt++ = *p_in_flt++;
3435 break;
3436 case RL2_SAMPLE_DOUBLE:
3437 *p_out_dbl++ = *p_in_dbl++;
3438 break;
3439 };
3440 }
3441 }
3442 }
3443
3444 free (tiff_scanline);
3445 TIFFClose (in);
3446 return RL2_OK;
3447 error:
3448 if (tiff_scanline != NULL)
3449 free (tiff_scanline);
3450 if (in != (TIFF *) 0)
3451 TIFFClose (in);
3452 return RL2_ERROR;
3453 }
3454
3455 static int
read_raw_separate_tiles(rl2PrivTiffOriginPtr origin,unsigned short width,unsigned short height,unsigned char sample_type,unsigned char num_bands,unsigned int startRow,unsigned int startCol,void * pixels)3456 read_raw_separate_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
3457 unsigned short height, unsigned char sample_type,
3458 unsigned char num_bands, unsigned int startRow,
3459 unsigned int startCol, void *pixels)
3460 {
3461 /* reading TIFF raw tiles - separate planes */
3462 uint32 tile_x;
3463 uint32 tile_y;
3464 uint32 x;
3465 uint32 y;
3466 uint32 *tiff_tile = NULL;
3467 unsigned char *p_in_u8;
3468 unsigned char *p_out_u8;
3469 unsigned short *p_in_u16;
3470 unsigned short *p_out_u16;
3471 unsigned int dest_x;
3472 unsigned int dest_y;
3473 int skip;
3474 unsigned char band;
3475
3476 if (sample_type != RL2_SAMPLE_UINT16 && sample_type != RL2_SAMPLE_UINT8)
3477 goto error;
3478
3479 tiff_tile = malloc (TIFFTileSize (origin->in));
3480 if (tiff_tile == NULL)
3481 goto error;
3482
3483 for (tile_y = 0; tile_y < origin->height; tile_y += origin->tileHeight)
3484 {
3485 /* scanning tiles by row */
3486 unsigned int tiff_min_y = tile_y;
3487 unsigned int tiff_max_y = tile_y + origin->tileHeight - 1;
3488 skip = 0;
3489 if (tiff_min_y > (startRow + height))
3490 skip = 1;
3491 if (tiff_max_y < startRow)
3492 skip = 1;
3493 if (skip)
3494 {
3495 /* skipping any not required tile */
3496 continue;
3497 }
3498 for (tile_x = 0; tile_x < origin->width; tile_x += origin->tileWidth)
3499 {
3500 /* reading a TIFF tile */
3501 unsigned int tiff_min_x = tile_x;
3502 unsigned int tiff_max_x = tile_x + origin->tileWidth - 1;
3503 skip = 0;
3504 if (tiff_min_x > (startCol + width))
3505 skip = 1;
3506 if (tiff_max_x < startCol)
3507 skip = 1;
3508 if (skip)
3509 {
3510 /* skipping any not required tile */
3511 continue;
3512 }
3513 for (band = 0; band < num_bands; band++)
3514 {
3515 /* one component for each separate plane */
3516 if (TIFFReadTile
3517 (origin->in, tiff_tile, tile_x, tile_y, 0, band) < 0)
3518 goto error;
3519 for (y = 0; y < origin->tileHeight; y++)
3520 {
3521 dest_y = tile_y + y;
3522 if (dest_y < startRow
3523 || dest_y >= (startRow + height))
3524 continue;
3525 for (x = 0; x < origin->tileWidth; x++)
3526 {
3527 dest_x = tile_x + x;
3528 if (dest_x < startCol
3529 || dest_x >= (startCol + width))
3530 continue;
3531 if (sample_type == RL2_SAMPLE_UINT16)
3532 {
3533 p_in_u16 = (unsigned short *) tiff_tile;
3534 p_in_u16 += y * origin->tileWidth;
3535 p_in_u16 += x;
3536 p_out_u16 = (unsigned short *) pixels;
3537 p_out_u16 +=
3538 ((dest_y -
3539 startRow) * width * num_bands) +
3540 ((dest_x - startCol) * num_bands) +
3541 band;
3542 *p_out_u16 = *p_in_u16;
3543 }
3544 if (sample_type == RL2_SAMPLE_UINT8)
3545 {
3546 p_in_u8 = (unsigned char *) tiff_tile;
3547 p_in_u8 += y * origin->tileWidth;
3548 p_in_u8 += x;
3549 p_out_u8 = (unsigned char *) pixels;
3550 p_out_u8 +=
3551 ((dest_y -
3552 startRow) * width * num_bands) +
3553 ((dest_x - startCol) * num_bands) +
3554 band;
3555 *p_out_u8 = *p_in_u8;
3556 }
3557 }
3558 }
3559 }
3560 }
3561 }
3562
3563 free (tiff_tile);
3564 return RL2_OK;
3565 error:
3566 if (tiff_tile != NULL)
3567 free (tiff_tile);
3568 return RL2_ERROR;
3569 }
3570
3571 static int
read_raw_separate_scanlines(rl2PrivTiffOriginPtr origin,unsigned short width,unsigned short height,unsigned char sample_type,unsigned char num_bands,unsigned int startRow,unsigned int startCol,void * pixels)3572 read_raw_separate_scanlines (rl2PrivTiffOriginPtr origin, unsigned short width,
3573 unsigned short height, unsigned char sample_type,
3574 unsigned char num_bands, unsigned int startRow,
3575 unsigned int startCol, void *pixels)
3576 {
3577 /* reading TIFF raw strips - separate planes */
3578 uint32 line_no;
3579 uint32 x;
3580 uint32 y;
3581 uint32 *tiff_scanline = NULL;
3582 unsigned char *p_in_u8;
3583 unsigned char *p_out_u8;
3584 unsigned char *p_out_u8_base;
3585 unsigned short *p_in_u16;
3586 unsigned short *p_out_u16;
3587 unsigned short *p_out_u16_base;
3588 unsigned char band;
3589 TIFF *in = (TIFF *) 0;
3590
3591 if (sample_type != RL2_SAMPLE_UINT8 && sample_type != RL2_SAMPLE_UINT16)
3592 goto error;
3593
3594 tiff_scanline = malloc (TIFFScanlineSize (origin->in));
3595 if (tiff_scanline == NULL)
3596 goto error;
3597
3598 for (band = 0; band < num_bands; band++)
3599 {
3600 /* one component for each separate plane */
3601
3602 /*
3603 / random access doesn't work on compressed scanlines
3604 / so we'll open an auxiliary TIFF handle, thus ensuring
3605 / an always clean reading context
3606 */
3607 in = TIFFOpen (origin->path, "r");
3608 if (in == NULL)
3609 goto error;
3610
3611 for (y = 0; y < startRow; y++)
3612 {
3613 /* skipping trailing scanlines */
3614 if (TIFFReadScanline (in, tiff_scanline, y, band) < 0)
3615 goto error;
3616 }
3617 for (y = 0; y < height; y++)
3618 {
3619 /* scanning scanlines by row */
3620 line_no = y + startRow;
3621 if (line_no >= origin->height)
3622 continue;
3623 if (TIFFReadScanline (in, tiff_scanline, line_no, band) < 0)
3624 goto error;
3625 if (sample_type == RL2_SAMPLE_UINT16)
3626 {
3627 p_in_u16 = (unsigned short *) tiff_scanline;
3628 p_in_u16 += startCol;
3629 p_out_u16_base = (unsigned short *) pixels;
3630 p_out_u16_base += y * width * num_bands;
3631 }
3632 else
3633 {
3634 p_in_u8 = (unsigned char *) tiff_scanline;
3635 p_in_u8 += startCol;
3636 p_out_u8_base = (unsigned char *) pixels;
3637 p_out_u8_base += y * width * num_bands;
3638 }
3639 for (x = startCol; x < origin->width; x++)
3640 {
3641 if (x >= (startCol + width))
3642 break;
3643 if (sample_type == RL2_SAMPLE_UINT16)
3644 p_out_u16 =
3645 p_out_u16_base + ((x - startCol) * num_bands) +
3646 band;
3647 else
3648 p_out_u8 =
3649 p_out_u8_base + ((x - startCol) * num_bands) +
3650 band;
3651 if (sample_type == RL2_SAMPLE_UINT16)
3652 *p_out_u16 = *p_in_u16++;
3653 else
3654 *p_out_u8 = *p_in_u8++;
3655 }
3656 }
3657 TIFFClose (in);
3658 in = (TIFF *) 0;
3659 }
3660
3661 free (tiff_scanline);
3662 return RL2_OK;
3663 error:
3664 if (tiff_scanline != NULL)
3665 free (tiff_scanline);
3666 if (in != (TIFF *) 0)
3667 TIFFClose (in);
3668 return RL2_ERROR;
3669 }
3670
3671 static int
read_RGBA_tiles(rl2PrivTiffOriginPtr origin,unsigned short width,unsigned short height,unsigned char pixel_type,unsigned char num_bands,unsigned int startRow,unsigned int startCol,unsigned char * pixels,rl2PalettePtr palette)3672 read_RGBA_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
3673 unsigned short height, unsigned char pixel_type,
3674 unsigned char num_bands, unsigned int startRow,
3675 unsigned int startCol, unsigned char *pixels,
3676 rl2PalettePtr palette)
3677 {
3678 /* reading TIFF RGBA tiles */
3679 uint32 tile_x;
3680 uint32 tile_y;
3681 uint32 x;
3682 uint32 y;
3683 uint32 pix;
3684 uint32 *tiff_tile = NULL;
3685 uint32 *p_in;
3686 unsigned char *p_out;
3687 unsigned int dest_x;
3688 unsigned int dest_y;
3689 int skip;
3690 unsigned char index;
3691 unsigned char red;
3692 unsigned char green;
3693 unsigned char blue;
3694
3695 tiff_tile =
3696 malloc (sizeof (uint32) * origin->tileWidth * origin->tileHeight);
3697 if (tiff_tile == NULL)
3698 goto error;
3699
3700 for (tile_y = 0; tile_y < origin->height; tile_y += origin->tileHeight)
3701 {
3702 /* scanning tiles by row */
3703 unsigned int tiff_min_y = tile_y;
3704 unsigned int tiff_max_y = tile_y + origin->tileHeight - 1;
3705 skip = 0;
3706 if (tiff_min_y > (startRow + height))
3707 skip = 1;
3708 if (tiff_max_y < startRow)
3709 skip = 1;
3710 if (skip)
3711 {
3712 /* skipping any not required tile */
3713 continue;
3714 }
3715 for (tile_x = 0; tile_x < origin->width; tile_x += origin->tileWidth)
3716 {
3717 /* reading a TIFF tile */
3718 unsigned int tiff_min_x = tile_x;
3719 unsigned int tiff_max_x = tile_x + origin->tileWidth - 1;
3720 skip = 0;
3721 if (tiff_min_x > (startCol + width))
3722 skip = 1;
3723 if (tiff_max_x < startCol)
3724 skip = 1;
3725 if (skip)
3726 {
3727 /* skipping any not required tile */
3728 continue;
3729 }
3730 if (!TIFFReadRGBATile (origin->in, tile_x, tile_y, tiff_tile))
3731 goto error;
3732 for (y = 0; y < origin->tileHeight; y++)
3733 {
3734 dest_y = tile_y + (origin->tileHeight - y) - 1;
3735 if (dest_y < startRow || dest_y >= (startRow + height))
3736 continue;
3737 p_in = tiff_tile + (origin->tileWidth * y);
3738 for (x = 0; x < origin->tileWidth; x++)
3739 {
3740 dest_x = tile_x + x;
3741 if (dest_x < startCol
3742 || dest_x >= (startCol + width))
3743 {
3744 p_in++;
3745 continue;
3746 }
3747 p_out =
3748 pixels +
3749 ((dest_y - startRow) * width * num_bands) +
3750 ((dest_x - startCol) * num_bands);
3751 pix = *p_in++;
3752 red = TIFFGetR (pix);
3753 green = TIFFGetG (pix);
3754 blue = TIFFGetB (pix);
3755 if (origin->forced_conversion ==
3756 RL2_CONVERT_RGB_TO_GRAYSCALE)
3757 {
3758 /* forced conversion: RGB -> GRAYSCALE */
3759 double gray =
3760 ((double) red * 0.2126) +
3761 ((double) green * 0.7152) +
3762 ((double) blue * 0.0722);
3763 *p_out++ = (unsigned char) gray;
3764 }
3765 else if (origin->forced_conversion ==
3766 RL2_CONVERT_GRAYSCALE_TO_RGB
3767 || origin->forced_conversion ==
3768 RL2_CONVERT_PALETTE_TO_RGB)
3769 {
3770 /* forced conversion: GRAYSCALE or PALETTE -> RGB */
3771 *p_out++ = red;
3772 *p_out++ = green;
3773 *p_out++ = blue;
3774 }
3775 else if (origin->forced_conversion ==
3776 RL2_CONVERT_GRAYSCALE_TO_PALETTE)
3777 {
3778 /* forced conversion: GRAYSCALE -> PALETTE */
3779 *p_out++ = red;
3780 }
3781 else if (origin->forced_conversion ==
3782 RL2_CONVERT_PALETTE_TO_GRAYSCALE)
3783 {
3784 /* forced conversion: PALETTE -> GRAYSCALE */
3785 *p_out++ = red;
3786 }
3787 else if (origin->forced_conversion ==
3788 RL2_CONVERT_PALETTE_TO_MONOCHROME)
3789 {
3790 /* forced conversion: PALETTE -> MONOCHROME */
3791 if (red == 255 && green == 255 && blue == 255)
3792 *p_out++ = 0;
3793 else
3794 *p_out++ = 1;
3795 }
3796 else if (origin->forced_conversion ==
3797 RL2_CONVERT_MONOCHROME_TO_PALETTE)
3798 {
3799 /* forced conversion: MONOCHROME -> PALETTE */
3800 if (red == 0)
3801 *p_out++ = 1;
3802 else
3803 *p_out++ = 0;
3804 }
3805 else if (pixel_type == RL2_PIXEL_PALETTE)
3806 {
3807 /* PALETTE image */
3808 if (rl2_get_palette_index
3809 (palette, &index, red, green,
3810 blue) != RL2_OK)
3811 index = 0;
3812 *p_out++ = index;
3813 }
3814 else if (pixel_type == RL2_PIXEL_MONOCHROME)
3815 {
3816 /* MONOCHROME image */
3817 if (red == 0)
3818 *p_out++ = 1;
3819 else
3820 *p_out++ = 0;
3821 }
3822 else if (pixel_type == RL2_PIXEL_GRAYSCALE)
3823 {
3824 /* GRAYSCALE image */
3825 *p_out++ = red;
3826 }
3827 else
3828 {
3829 /* should be an RGB image */
3830 *p_out++ = red;
3831 *p_out++ = green;
3832 *p_out++ = blue;
3833 }
3834 }
3835 }
3836 }
3837 }
3838
3839 free (tiff_tile);
3840 return RL2_OK;
3841 error:
3842 if (tiff_tile != NULL)
3843 free (tiff_tile);
3844 return RL2_ERROR;
3845 }
3846
3847 static int
read_RGBA_strips(rl2PrivTiffOriginPtr origin,unsigned short width,unsigned short height,unsigned char pixel_type,unsigned char num_bands,unsigned int startRow,unsigned int startCol,unsigned char * pixels,rl2PalettePtr palette)3848 read_RGBA_strips (rl2PrivTiffOriginPtr origin, unsigned short width,
3849 unsigned short height, unsigned char pixel_type,
3850 unsigned char num_bands, unsigned int startRow,
3851 unsigned int startCol, unsigned char *pixels,
3852 rl2PalettePtr palette)
3853 {
3854 /* reading TIFF RGBA strips */
3855 uint32 strip;
3856 uint32 x;
3857 uint32 y;
3858 uint32 pix;
3859 uint32 *tiff_strip = NULL;
3860 uint32 *p_in;
3861 unsigned char *p_out;
3862 unsigned int dest_x;
3863 unsigned int dest_y;
3864 int skip;
3865 unsigned char index;
3866 unsigned char red;
3867 unsigned char green;
3868 unsigned char blue;
3869
3870 tiff_strip =
3871 malloc (sizeof (uint32) * origin->width * origin->rowsPerStrip);
3872 if (tiff_strip == NULL)
3873 goto error;
3874
3875 for (strip = 0; strip < origin->height; strip += origin->rowsPerStrip)
3876 {
3877 /* scanning strips by row */
3878 unsigned int tiff_min_y = strip;
3879 unsigned int tiff_max_y = strip + origin->rowsPerStrip - 1;
3880 skip = 0;
3881 if (tiff_min_y > (startRow + height))
3882 skip = 1;
3883 if (tiff_max_y < startRow)
3884 skip = 1;
3885 if (skip)
3886 {
3887 /* skipping any not required strip */
3888 continue;
3889 }
3890 if (!TIFFReadRGBAStrip (origin->in, strip, tiff_strip))
3891 goto error;
3892 for (y = 0; y < origin->rowsPerStrip; y++)
3893 {
3894 dest_y = strip + (origin->rowsPerStrip - y) - 1;
3895 if (dest_y < startRow || dest_y >= (startRow + height))
3896 continue;
3897 p_in = tiff_strip + (origin->width * y);
3898 for (x = 0; x < origin->width; x++)
3899 {
3900 dest_x = x;
3901 if (dest_x < startCol || dest_x >= (startCol + width))
3902 {
3903 p_in++;
3904 continue;
3905 }
3906 p_out =
3907 pixels + ((dest_y - startRow) * width * num_bands) +
3908 ((dest_x - startCol) * num_bands);
3909 pix = *p_in++;
3910 red = TIFFGetR (pix);
3911 green = TIFFGetG (pix);
3912 blue = TIFFGetB (pix);
3913 if (origin->forced_conversion ==
3914 RL2_CONVERT_RGB_TO_GRAYSCALE)
3915 {
3916 /* forced conversion: RGB -> GRAYSCALE */
3917 double gray =
3918 ((double) red * 0.2126) +
3919 ((double) green * 0.7152) +
3920 ((double) blue * 0.0722);
3921 *p_out++ = (unsigned char) gray;
3922 }
3923 else if (origin->forced_conversion ==
3924 RL2_CONVERT_GRAYSCALE_TO_RGB
3925 || origin->forced_conversion ==
3926 RL2_CONVERT_PALETTE_TO_RGB)
3927 {
3928 /* forced conversion: GRAYSCALE or PALETTE -> RGB */
3929 *p_out++ = red;
3930 *p_out++ = green;
3931 *p_out++ = blue;
3932 }
3933 else if (origin->forced_conversion ==
3934 RL2_CONVERT_GRAYSCALE_TO_PALETTE)
3935 {
3936 /* forced conversion: GRAYSCALE -> PALETTE */
3937 *p_out++ = red;
3938 }
3939 else if (origin->forced_conversion ==
3940 RL2_CONVERT_PALETTE_TO_GRAYSCALE)
3941 {
3942 /* forced conversion: PALETTE -> GRAYSCALE */
3943 *p_out++ = red;
3944 }
3945 else if (origin->forced_conversion ==
3946 RL2_CONVERT_PALETTE_TO_MONOCHROME)
3947 {
3948 /* forced conversion: PALETTE -> MONOCHROME */
3949 if (red == 255 && green == 255 && blue == 255)
3950 *p_out++ = 0;
3951 else
3952 *p_out++ = 1;
3953 }
3954 else if (origin->forced_conversion ==
3955 RL2_CONVERT_MONOCHROME_TO_PALETTE)
3956 {
3957 /* forced conversion: MONOCHROME -> PALETTE */
3958 if (red == 0)
3959 *p_out++ = 1;
3960 else
3961 *p_out++ = 0;
3962 }
3963 else if (pixel_type == RL2_PIXEL_PALETTE)
3964 {
3965 /* PALETTE image */
3966 if (rl2_get_palette_index
3967 (palette, &index, red, green, blue) != RL2_OK)
3968 index = 0;
3969 *p_out++ = index;
3970 }
3971 else if (pixel_type == RL2_PIXEL_MONOCHROME)
3972 {
3973 /* MONOCHROME image */
3974 if (red == 0)
3975 *p_out++ = 1;
3976 else
3977 *p_out++ = 0;
3978 }
3979 else if (pixel_type == RL2_PIXEL_GRAYSCALE)
3980 {
3981 /* GRAYSCALE image */
3982 *p_out++ = red;
3983 }
3984 else
3985 {
3986 /* should be an RGB image */
3987 *p_out++ = red;
3988 *p_out++ = green;
3989 *p_out++ = blue;
3990 }
3991 }
3992 }
3993 }
3994
3995 free (tiff_strip);
3996 return RL2_OK;
3997 error:
3998 if (tiff_strip != NULL)
3999 free (tiff_strip);
4000 return RL2_ERROR;
4001 }
4002
4003 static int
read_from_tiff(rl2PrivTiffOriginPtr origin,unsigned short width,unsigned short height,unsigned char sample_type,unsigned char pixel_type,unsigned char num_bands,unsigned int startRow,unsigned int startCol,unsigned char ** pixels,int * pixels_sz,rl2PalettePtr palette)4004 read_from_tiff (rl2PrivTiffOriginPtr origin, unsigned short width,
4005 unsigned short height, unsigned char sample_type,
4006 unsigned char pixel_type, unsigned char num_bands,
4007 unsigned int startRow, unsigned int startCol,
4008 unsigned char **pixels, int *pixels_sz, rl2PalettePtr palette)
4009 {
4010 /* creating a tile from the Tiff origin */
4011 int ret;
4012 unsigned char *bufPixels = NULL;
4013 int bufPixelsSz = 0;
4014 int pix_sz = 1;
4015
4016 /* allocating the pixels buffer */
4017 switch (sample_type)
4018 {
4019 case RL2_SAMPLE_INT16:
4020 case RL2_SAMPLE_UINT16:
4021 pix_sz = 2;
4022 break;
4023 case RL2_SAMPLE_INT32:
4024 case RL2_SAMPLE_UINT32:
4025 case RL2_SAMPLE_FLOAT:
4026 pix_sz = 4;
4027 break;
4028 case RL2_SAMPLE_DOUBLE:
4029 pix_sz = 8;
4030 break;
4031 };
4032 bufPixelsSz = width * height * pix_sz * num_bands;
4033 bufPixels = malloc (bufPixelsSz);
4034 if (bufPixels == NULL)
4035 goto error;
4036 if ((startRow + height) > origin->height
4037 || (startCol + width) > origin->width)
4038 rl2_prime_void_tile (bufPixels, width, height, sample_type, num_bands,
4039 NULL);
4040
4041 if (origin->planarConfig == PLANARCONFIG_SEPARATE)
4042 {
4043 /* separate planes configuration */
4044 if ((origin->bitsPerSample == 16 || origin->bitsPerSample == 8)
4045 && origin->sampleFormat == SAMPLEFORMAT_UINT)
4046 {
4047 /* using raw TIFF methods - separate planes */
4048 if (origin->isTiled)
4049 ret =
4050 read_raw_separate_tiles (origin, width, height,
4051 sample_type, num_bands,
4052 startRow, startCol,
4053 (void *) bufPixels);
4054 else
4055 ret =
4056 read_raw_separate_scanlines (origin, width, height,
4057 sample_type, num_bands,
4058 startRow, startCol,
4059 (void *) bufPixels);
4060 if (ret != RL2_OK)
4061 goto error;
4062 }
4063 else
4064 goto error;
4065 }
4066 else
4067 {
4068 /* contiguous planar configuration */
4069 if (origin->bitsPerSample <= 8
4070 && origin->sampleFormat == SAMPLEFORMAT_UINT
4071 && (origin->samplesPerPixel == 1 || origin->samplesPerPixel == 3)
4072 && (pixel_type == RL2_PIXEL_MONOCHROME
4073 || pixel_type == RL2_PIXEL_PALETTE
4074 || pixel_type == RL2_PIXEL_GRAYSCALE
4075 || pixel_type == RL2_PIXEL_RGB))
4076 {
4077 /* using the TIFF RGBA methods */
4078 if (origin->isTiled)
4079 ret =
4080 read_RGBA_tiles (origin, width, height, pixel_type,
4081 num_bands, startRow, startCol,
4082 bufPixels, palette);
4083 else
4084 ret =
4085 read_RGBA_strips (origin, width, height, pixel_type,
4086 num_bands, startRow, startCol,
4087 bufPixels, palette);
4088 if (ret != RL2_OK)
4089 goto error;
4090 }
4091 else
4092 {
4093 /* using raw TIFF methods */
4094 if (origin->isTiled)
4095 ret =
4096 read_raw_tiles (origin, width, height, sample_type,
4097 num_bands, startRow, startCol,
4098 bufPixels);
4099 else
4100 ret =
4101 read_raw_scanlines (origin, width, height, sample_type,
4102 num_bands, startRow, startCol,
4103 bufPixels);
4104 if (ret != RL2_OK)
4105 goto error;
4106 }
4107 }
4108
4109 *pixels = bufPixels;
4110 *pixels_sz = bufPixelsSz;
4111 return RL2_OK;
4112 error:
4113 if (bufPixels != NULL)
4114 free (bufPixels);
4115 return RL2_ERROR;
4116 }
4117
4118 RL2_DECLARE int
rl2_is_tiled_tiff_origin(rl2TiffOriginPtr tiff,int * is_tiled)4119 rl2_is_tiled_tiff_origin (rl2TiffOriginPtr tiff, int *is_tiled)
4120 {
4121 /* testing if the TIFF Origin is tiled or not */
4122 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
4123 if (origin == NULL)
4124 return RL2_ERROR;
4125 *is_tiled = origin->isTiled;
4126 return RL2_OK;
4127 }
4128
4129 RL2_DECLARE int
rl2_get_tiff_origin_tile_size(rl2TiffOriginPtr tiff,unsigned int * tile_width,unsigned int * tile_height)4130 rl2_get_tiff_origin_tile_size (rl2TiffOriginPtr tiff,
4131 unsigned int *tile_width,
4132 unsigned int *tile_height)
4133 {
4134 /* attempting to return the Tile dimensions */
4135 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
4136 if (origin == NULL)
4137 return RL2_ERROR;
4138 if (origin->isTiled == 0)
4139 return RL2_ERROR;
4140 *tile_width = origin->tileWidth;
4141 *tile_height = origin->tileHeight;
4142 return RL2_OK;
4143 }
4144
4145 RL2_DECLARE int
rl2_get_tiff_origin_strip_size(rl2TiffOriginPtr tiff,unsigned int * strip_size)4146 rl2_get_tiff_origin_strip_size (rl2TiffOriginPtr tiff, unsigned int *strip_size)
4147 {
4148 /* attempting to return the Strip dimension */
4149 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
4150 if (origin == NULL)
4151 return RL2_ERROR;
4152 if (origin->isTiled != 0)
4153 return RL2_ERROR;
4154 *strip_size = origin->rowsPerStrip;
4155 return RL2_OK;
4156 }
4157
4158 static void
build_remap(rl2PrivTiffOriginPtr origin)4159 build_remap (rl2PrivTiffOriginPtr origin)
4160 {
4161 /* building a remapped palette identical to the natural one */
4162 int j;
4163 if (origin->remapRed != NULL)
4164 free (origin->remapRed);
4165 if (origin->remapGreen != NULL)
4166 free (origin->remapGreen);
4167 if (origin->remapBlue != NULL)
4168 free (origin->remapBlue);
4169 origin->remapMaxPalette = origin->maxPalette;
4170 origin->remapRed = malloc (origin->remapMaxPalette);
4171 origin->remapGreen = malloc (origin->remapMaxPalette);
4172 origin->remapBlue = malloc (origin->remapMaxPalette);
4173 for (j = 0; j < origin->maxPalette; j++)
4174 {
4175 origin->remapRed[j] = origin->red[j];
4176 origin->remapGreen[j] = origin->green[j];
4177 origin->remapBlue[j] = origin->blue[j];
4178 }
4179 }
4180
4181 RL2_DECLARE rl2RasterPtr
rl2_get_tile_from_tiff_origin(rl2CoveragePtr cvg,rl2TiffOriginPtr tiff,unsigned int startRow,unsigned int startCol,int force_srid)4182 rl2_get_tile_from_tiff_origin (rl2CoveragePtr cvg, rl2TiffOriginPtr tiff,
4183 unsigned int startRow, unsigned int startCol,
4184 int force_srid)
4185 {
4186 /* attempting to create a Coverage-tile from a Tiff origin */
4187 unsigned int x;
4188 rl2PrivCoveragePtr coverage = (rl2PrivCoveragePtr) cvg;
4189 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
4190 rl2RasterPtr raster = NULL;
4191 rl2PalettePtr palette = NULL;
4192 unsigned char *pixels = NULL;
4193 int pixels_sz = 0;
4194 unsigned char *mask = NULL;
4195 int mask_size = 0;
4196 unsigned int unused_width = 0;
4197 unsigned int unused_height = 0;
4198
4199 if (coverage == NULL || tiff == NULL)
4200 return NULL;
4201 if (rl2_eval_tiff_origin_compatibility (cvg, tiff, force_srid) != RL2_TRUE)
4202 return NULL;
4203
4204 /* testing for tile's boundary validity */
4205 if (startCol > origin->width)
4206 return NULL;
4207 if (startRow > origin->height)
4208 return NULL;
4209 x = startCol / coverage->tileWidth;
4210 if ((x * coverage->tileWidth) != startCol)
4211 return NULL;
4212 x = startRow / coverage->tileHeight;
4213 if ((x * coverage->tileHeight) != startRow)
4214 return NULL;
4215
4216 if ((origin->photometric == PHOTOMETRIC_RGB
4217 && origin->forced_pixel_type == RL2_PIXEL_PALETTE)
4218 || origin->forced_conversion == RL2_CONVERT_GRAYSCALE_TO_PALETTE)
4219 {
4220 /* creating a remapped Palette */
4221 if (origin->remapMaxPalette == 0 && origin->maxPalette > 0
4222 && origin->maxPalette <= 256)
4223 build_remap (origin);
4224 palette = rl2_create_palette (origin->remapMaxPalette);
4225 for (x = 0; x < origin->remapMaxPalette; x++)
4226 {
4227 rl2_set_palette_color (palette, x, origin->remapRed[x],
4228 origin->remapGreen[x],
4229 origin->remapBlue[x]);
4230 }
4231 }
4232 else if ((origin->photometric < PHOTOMETRIC_RGB
4233 && origin->forced_pixel_type == RL2_PIXEL_PALETTE)
4234 || origin->forced_conversion == RL2_CONVERT_MONOCHROME_TO_PALETTE)
4235 {
4236 /* creating a remapped Palette */
4237 if (origin->remapMaxPalette == 0 && origin->maxPalette > 0
4238 && origin->maxPalette <= 2)
4239 build_remap (origin);
4240 palette = rl2_create_palette (origin->remapMaxPalette);
4241 for (x = 0; x < origin->remapMaxPalette; x++)
4242 {
4243 rl2_set_palette_color (palette, x, origin->remapRed[x],
4244 origin->remapGreen[x],
4245 origin->remapBlue[x]);
4246 }
4247 }
4248 if (origin->photometric == PHOTOMETRIC_PALETTE)
4249 {
4250 /* creating an ordinary Palette */
4251 if (origin->remapMaxPalette > 0)
4252 {
4253 palette = rl2_create_palette (origin->remapMaxPalette);
4254 for (x = 0; x < origin->maxPalette; x++)
4255 {
4256 rl2_set_palette_color (palette, x,
4257 origin->remapRed[x],
4258 origin->remapGreen[x],
4259 origin->remapBlue[x]);
4260 }
4261 }
4262 else
4263 {
4264 if (origin->maxPalette > 0)
4265 {
4266 palette = rl2_create_palette (origin->maxPalette);
4267 for (x = 0; x < origin->maxPalette; x++)
4268 {
4269 rl2_set_palette_color (palette, x, origin->red[x],
4270 origin->green[x],
4271 origin->blue[x]);
4272 }
4273 }
4274 }
4275 }
4276
4277 /* attempting to create the tile */
4278 if (read_from_tiff
4279 (origin, coverage->tileWidth, coverage->tileHeight,
4280 coverage->sampleType, coverage->pixelType, coverage->nBands, startRow,
4281 startCol, &pixels, &pixels_sz, palette) != RL2_OK)
4282 goto error;
4283 if (startCol + coverage->tileWidth > origin->width)
4284 unused_width = (startCol + coverage->tileWidth) - origin->width;
4285 if (startRow + coverage->tileHeight > origin->height)
4286 unused_height = (startRow + coverage->tileHeight) - origin->height;
4287 if (unused_width || unused_height)
4288 {
4289 /*
4290 * creating a Transparency Mask so to shadow any
4291 * unused portion of the current tile
4292 */
4293 unsigned int shadow_x = coverage->tileWidth - unused_width;
4294 unsigned int shadow_y = coverage->tileHeight - unused_height;
4295 unsigned int row;
4296 mask_size = coverage->tileWidth * coverage->tileHeight;
4297 mask = malloc (mask_size);
4298 if (mask == NULL)
4299 goto error;
4300 /* full Transparent mask */
4301 memset (mask, 0, coverage->tileWidth * coverage->tileHeight);
4302 for (row = 0; row < coverage->tileHeight; row++)
4303 {
4304 unsigned char *p = mask + (row * coverage->tileWidth);
4305 if (row < shadow_y)
4306 {
4307 /* setting opaque pixels */
4308 memset (p, 1, shadow_x);
4309 }
4310 }
4311 }
4312
4313 if (origin->forced_conversion == RL2_CONVERT_PALETTE_TO_MONOCHROME ||
4314 origin->forced_conversion == RL2_CONVERT_PALETTE_TO_GRAYSCALE ||
4315 origin->forced_conversion == RL2_CONVERT_PALETTE_TO_RGB)
4316 {
4317 rl2_destroy_palette (palette);
4318 palette = NULL;
4319 }
4320 raster =
4321 rl2_create_raster (coverage->tileWidth, coverage->tileHeight,
4322 coverage->sampleType, coverage->pixelType,
4323 coverage->nBands, pixels, pixels_sz, palette, mask,
4324 mask_size, NULL);
4325 if (raster == NULL)
4326 goto error;
4327 return raster;
4328 error:
4329 if (palette != NULL)
4330 rl2_destroy_palette (palette);
4331 if (pixels != NULL)
4332 free (pixels);
4333 if (mask != NULL)
4334 free (mask);
4335 return NULL;
4336 }
4337
4338 static rl2PrivTiffDestinationPtr
create_tiff_destination(const char * path,int is_geo_tiff)4339 create_tiff_destination (const char *path, int is_geo_tiff)
4340 {
4341 /* creating an uninitialized TIFF destination */
4342 int len;
4343 rl2PrivTiffDestinationPtr destination;
4344 if (path == NULL)
4345 return NULL;
4346 destination = malloc (sizeof (rl2PrivTiffDestination));
4347 if (destination == NULL)
4348 return NULL;
4349
4350 len = strlen (path);
4351 destination->path = malloc (len + 1);
4352 strcpy (destination->path, path);
4353 destination->isGeoTiff = is_geo_tiff;
4354 destination->out = (TIFF *) 0;
4355 destination->gtif = (GTIF *) 0;
4356 destination->tiffBuffer = NULL;
4357 destination->tileWidth = 256;
4358 destination->tileHeight = 256;
4359 destination->maxPalette = 0;
4360 destination->red = NULL;
4361 destination->green = NULL;
4362 destination->blue = NULL;
4363 destination->isGeoReferenced = 0;
4364 destination->Srid = -1;
4365 destination->srsName = NULL;
4366 destination->proj4text = NULL;
4367 return destination;
4368 }
4369
4370 RL2_DECLARE void
rl2_destroy_tiff_destination(rl2TiffDestinationPtr tiff)4371 rl2_destroy_tiff_destination (rl2TiffDestinationPtr tiff)
4372 {
4373 /* memory cleanup - destroying a TIFF destination */
4374 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
4375 if (destination == NULL)
4376 return;
4377 if (destination->isGeoTiff)
4378 {
4379 /* it's a GeoTiff */
4380 if (destination->gtif != (GTIF *) 0)
4381 GTIFFree (destination->gtif);
4382 if (destination->out != (TIFF *) 0)
4383 XTIFFClose (destination->out);
4384 }
4385 else
4386 {
4387 /* it's a plain ordinary Tiff */
4388 if (destination->out != (TIFF *) 0)
4389 TIFFClose (destination->out);
4390 }
4391 if (destination->path != NULL)
4392 free (destination->path);
4393 if (destination->tfw_path != NULL)
4394 free (destination->tfw_path);
4395 if (destination->tiffBuffer != NULL)
4396 free (destination->tiffBuffer);
4397 if (destination->red != NULL)
4398 free (destination->red);
4399 if (destination->green != NULL)
4400 free (destination->green);
4401 if (destination->blue != NULL)
4402 free (destination->blue);
4403 if (destination->srsName != NULL)
4404 free (destination->srsName);
4405 if (destination->proj4text != NULL)
4406 free (destination->proj4text);
4407 free (destination);
4408 }
4409
4410 static int
check_color_model(unsigned char sample_type,unsigned char pixel_type,unsigned char num_bands,rl2PalettePtr plt,unsigned char compression)4411 check_color_model (unsigned char sample_type, unsigned char pixel_type,
4412 unsigned char num_bands, rl2PalettePtr plt,
4413 unsigned char compression)
4414 {
4415 /* checking TIFF arguments for self consistency */
4416 switch (pixel_type)
4417 {
4418 case RL2_PIXEL_MONOCHROME:
4419 if (sample_type != RL2_SAMPLE_1_BIT || num_bands != 1)
4420 return 0;
4421 switch (compression)
4422 {
4423 case RL2_COMPRESSION_NONE:
4424 case RL2_COMPRESSION_CCITTFAX3:
4425 case RL2_COMPRESSION_CCITTFAX4:
4426 break;
4427 default:
4428 return 0;
4429 };
4430 break;
4431 case RL2_PIXEL_PALETTE:
4432 switch (sample_type)
4433 {
4434 case RL2_SAMPLE_1_BIT:
4435 case RL2_SAMPLE_2_BIT:
4436 case RL2_SAMPLE_4_BIT:
4437 case RL2_SAMPLE_UINT8:
4438 break;
4439 default:
4440 return 0;
4441 };
4442 if (num_bands != 1)
4443 return 0;
4444 if (plt == NULL)
4445 return 0;
4446 switch (compression)
4447 {
4448 case RL2_COMPRESSION_NONE:
4449 case RL2_COMPRESSION_DEFLATE:
4450 case RL2_COMPRESSION_LZMA:
4451 case RL2_COMPRESSION_LZW:
4452 break;
4453 default:
4454 return 0;
4455 };
4456 break;
4457 case RL2_PIXEL_GRAYSCALE:
4458 switch (sample_type)
4459 {
4460 case RL2_SAMPLE_1_BIT:
4461 case RL2_SAMPLE_2_BIT:
4462 case RL2_SAMPLE_4_BIT:
4463 case RL2_SAMPLE_UINT8:
4464 break;
4465 default:
4466 return 0;
4467 };
4468 if (num_bands != 1)
4469 return 0;
4470 switch (compression)
4471 {
4472 case RL2_COMPRESSION_NONE:
4473 case RL2_COMPRESSION_DEFLATE:
4474 case RL2_COMPRESSION_LZMA:
4475 case RL2_COMPRESSION_LZW:
4476 case RL2_COMPRESSION_JPEG:
4477 break;
4478 default:
4479 return 0;
4480 };
4481 break;
4482 case RL2_PIXEL_RGB:
4483 switch (sample_type)
4484 {
4485 case RL2_SAMPLE_UINT8:
4486 case RL2_SAMPLE_UINT16:
4487 break;
4488 default:
4489 return 0;
4490 };
4491 if (num_bands != 3)
4492 return 0;
4493 if (sample_type == RL2_SAMPLE_UINT16)
4494 {
4495 switch (compression)
4496 {
4497 case RL2_COMPRESSION_NONE:
4498 case RL2_COMPRESSION_DEFLATE:
4499 case RL2_COMPRESSION_LZMA:
4500 case RL2_COMPRESSION_LZW:
4501 break;
4502 default:
4503 return 0;
4504 };
4505 }
4506 else
4507 {
4508 switch (compression)
4509 {
4510 case RL2_COMPRESSION_NONE:
4511 case RL2_COMPRESSION_DEFLATE:
4512 case RL2_COMPRESSION_LZMA:
4513 case RL2_COMPRESSION_LZW:
4514 case RL2_COMPRESSION_JPEG:
4515 break;
4516 default:
4517 return 0;
4518 };
4519 }
4520 break;
4521 case RL2_PIXEL_DATAGRID:
4522 switch (sample_type)
4523 {
4524 case RL2_SAMPLE_INT8:
4525 case RL2_SAMPLE_UINT8:
4526 case RL2_SAMPLE_INT16:
4527 case RL2_SAMPLE_UINT16:
4528 case RL2_SAMPLE_INT32:
4529 case RL2_SAMPLE_UINT32:
4530 case RL2_SAMPLE_FLOAT:
4531 case RL2_SAMPLE_DOUBLE:
4532 break;
4533 default:
4534 return 0;
4535 };
4536 if (num_bands != 1)
4537 return 0;
4538 switch (compression)
4539 {
4540 case RL2_COMPRESSION_NONE:
4541 case RL2_COMPRESSION_DEFLATE:
4542 case RL2_COMPRESSION_LZMA:
4543 case RL2_COMPRESSION_LZW:
4544 break;
4545 default:
4546 return 0;
4547 };
4548 break;
4549 };
4550 return 1;
4551 }
4552
4553 static int
set_tiff_destination(rl2PrivTiffDestinationPtr destination,unsigned short width,unsigned short height,unsigned char sample_type,unsigned char pixel_type,unsigned char num_bands,rl2PalettePtr plt,unsigned char tiff_compression)4554 set_tiff_destination (rl2PrivTiffDestinationPtr destination,
4555 unsigned short width, unsigned short height,
4556 unsigned char sample_type, unsigned char pixel_type,
4557 unsigned char num_bands, rl2PalettePtr plt,
4558 unsigned char tiff_compression)
4559 {
4560 /* setting up the TIFF headers */
4561 int i;
4562 uint16 r_plt[256];
4563 uint16 g_plt[256];
4564 uint16 b_plt[256];
4565 tsize_t buf_size;
4566 void *tiff_buffer = NULL;
4567
4568 TIFFSetField (destination->out, TIFFTAG_SUBFILETYPE, 0);
4569 TIFFSetField (destination->out, TIFFTAG_IMAGEWIDTH, width);
4570 TIFFSetField (destination->out, TIFFTAG_IMAGELENGTH, height);
4571 TIFFSetField (destination->out, TIFFTAG_XRESOLUTION, 300.0);
4572 TIFFSetField (destination->out, TIFFTAG_YRESOLUTION, 300.0);
4573 TIFFSetField (destination->out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
4574 if (pixel_type == RL2_PIXEL_MULTIBAND)
4575 TIFFSetField (destination->out, TIFFTAG_PLANARCONFIG,
4576 PLANARCONFIG_SEPARATE);
4577 else if (pixel_type == RL2_PIXEL_RGB && sample_type == RL2_SAMPLE_UINT16)
4578 TIFFSetField (destination->out, TIFFTAG_PLANARCONFIG,
4579 PLANARCONFIG_SEPARATE);
4580 else
4581 TIFFSetField (destination->out, TIFFTAG_PLANARCONFIG,
4582 PLANARCONFIG_CONTIG);
4583 TIFFSetField (destination->out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
4584 if (pixel_type == RL2_PIXEL_MONOCHROME)
4585 {
4586 /* MONOCHROME */
4587 destination->sampleFormat = SAMPLEFORMAT_UINT;
4588 destination->bitsPerSample = 1;
4589 destination->samplesPerPixel = 1;
4590 destination->photometric = PHOTOMETRIC_MINISWHITE;
4591 TIFFSetField (destination->out, TIFFTAG_SAMPLEFORMAT,
4592 SAMPLEFORMAT_UINT);
4593 TIFFSetField (destination->out, TIFFTAG_SAMPLESPERPIXEL, 1);
4594 TIFFSetField (destination->out, TIFFTAG_BITSPERSAMPLE, 1);
4595 TIFFSetField (destination->out, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
4596 TIFFSetField (destination->out, TIFFTAG_PHOTOMETRIC,
4597 PHOTOMETRIC_MINISWHITE);
4598 if (tiff_compression == RL2_COMPRESSION_CCITTFAX3)
4599 {
4600 destination->compression = COMPRESSION_CCITTFAX3;
4601 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4602 COMPRESSION_CCITTFAX3);
4603 }
4604 else if (tiff_compression == RL2_COMPRESSION_CCITTFAX4)
4605 {
4606 destination->compression = COMPRESSION_CCITTFAX4;
4607 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4608 COMPRESSION_CCITTFAX4);
4609 }
4610 else
4611 {
4612 destination->compression = COMPRESSION_NONE;
4613 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4614 COMPRESSION_NONE);
4615 }
4616 goto header_done;
4617 }
4618 else if (pixel_type == RL2_PIXEL_PALETTE)
4619 {
4620 /* PALETTE */
4621 unsigned short max_palette;
4622 unsigned char *red;
4623 unsigned char *green;
4624 unsigned char *blue;
4625 if (rl2_get_palette_colors
4626 (plt, &max_palette, &red, &green, &blue) == RL2_ERROR)
4627 {
4628 fprintf (stderr, "RL2-TIFF writer: invalid Palette\n");
4629 goto error;
4630 }
4631 for (i = 0; i < 256; i++)
4632 {
4633 r_plt[i] = 0;
4634 g_plt[i] = 0;
4635 b_plt[i] = 0;
4636 }
4637 for (i = 0; i < max_palette; i++)
4638 {
4639 r_plt[i] = red[i] * 256;
4640 g_plt[i] = green[i] * 256;
4641 b_plt[i] = blue[i] * 256;
4642 }
4643 rl2_free (red);
4644 rl2_free (green);
4645 rl2_free (blue);
4646 destination->sampleFormat = SAMPLEFORMAT_UINT;
4647 destination->bitsPerSample = 8;
4648 destination->samplesPerPixel = 1;
4649 destination->photometric = PHOTOMETRIC_PALETTE;
4650 TIFFSetField (destination->out, TIFFTAG_SAMPLEFORMAT,
4651 SAMPLEFORMAT_UINT);
4652 TIFFSetField (destination->out, TIFFTAG_SAMPLESPERPIXEL, 1);
4653 TIFFSetField (destination->out, TIFFTAG_BITSPERSAMPLE, 8);
4654 TIFFSetField (destination->out, TIFFTAG_PHOTOMETRIC,
4655 PHOTOMETRIC_PALETTE);
4656 TIFFSetField (destination->out, TIFFTAG_COLORMAP, r_plt, g_plt,
4657 b_plt);
4658 if (tiff_compression == RL2_COMPRESSION_LZW)
4659 {
4660 destination->compression = COMPRESSION_LZW;
4661 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4662 COMPRESSION_LZW);
4663 }
4664 else if (tiff_compression == RL2_COMPRESSION_DEFLATE)
4665 {
4666 destination->compression = COMPRESSION_DEFLATE;
4667 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4668 COMPRESSION_DEFLATE);
4669 }
4670 else if (tiff_compression == RL2_COMPRESSION_LZMA)
4671 {
4672 destination->compression = COMPRESSION_LZMA;
4673 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4674 COMPRESSION_LZMA);
4675 }
4676 else
4677 {
4678 destination->compression = COMPRESSION_NONE;
4679 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4680 COMPRESSION_NONE);
4681 }
4682 goto header_done;
4683 }
4684 else if (pixel_type == RL2_PIXEL_GRAYSCALE)
4685 {
4686 /* GRAYSCALE */
4687 destination->sampleFormat = SAMPLEFORMAT_UINT;
4688 destination->bitsPerSample = 8;
4689 destination->samplesPerPixel = 1;
4690 destination->photometric = PHOTOMETRIC_MINISBLACK;
4691 TIFFSetField (destination->out, TIFFTAG_SAMPLEFORMAT,
4692 SAMPLEFORMAT_UINT);
4693 TIFFSetField (destination->out, TIFFTAG_SAMPLESPERPIXEL, 1);
4694 TIFFSetField (destination->out, TIFFTAG_BITSPERSAMPLE, 8);
4695 TIFFSetField (destination->out, TIFFTAG_PHOTOMETRIC,
4696 PHOTOMETRIC_MINISBLACK);
4697 if (tiff_compression == RL2_COMPRESSION_LZW)
4698 {
4699 destination->compression = COMPRESSION_LZW;
4700 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4701 COMPRESSION_LZW);
4702 }
4703 else if (tiff_compression == RL2_COMPRESSION_DEFLATE)
4704 {
4705 destination->compression = COMPRESSION_DEFLATE;
4706 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4707 COMPRESSION_DEFLATE);
4708 }
4709 else if (tiff_compression == RL2_COMPRESSION_LZMA)
4710 {
4711 destination->compression = COMPRESSION_LZMA;
4712 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4713 COMPRESSION_LZMA);
4714 }
4715 else if (tiff_compression == RL2_COMPRESSION_JPEG)
4716 {
4717 destination->compression = COMPRESSION_JPEG;
4718 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4719 COMPRESSION_JPEG);
4720 }
4721 else
4722 {
4723 destination->compression = COMPRESSION_NONE;
4724 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4725 COMPRESSION_NONE);
4726 }
4727 goto header_done;
4728 }
4729 else if (pixel_type == RL2_PIXEL_RGB)
4730 {
4731 /* RGB */
4732 destination->sampleFormat = SAMPLEFORMAT_UINT;
4733 if (sample_type == RL2_SAMPLE_UINT16)
4734 destination->bitsPerSample = 16;
4735 else
4736 destination->bitsPerSample = 8;
4737 destination->samplesPerPixel = 3;
4738 destination->photometric = PHOTOMETRIC_RGB;
4739 TIFFSetField (destination->out, TIFFTAG_SAMPLEFORMAT,
4740 SAMPLEFORMAT_UINT);
4741 TIFFSetField (destination->out, TIFFTAG_SAMPLESPERPIXEL, 3);
4742 TIFFSetField (destination->out, TIFFTAG_BITSPERSAMPLE,
4743 destination->bitsPerSample);
4744 TIFFSetField (destination->out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
4745 if (tiff_compression == RL2_COMPRESSION_LZW)
4746 {
4747 destination->compression = COMPRESSION_LZW;
4748 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4749 COMPRESSION_LZW);
4750 }
4751 else if (tiff_compression == RL2_COMPRESSION_DEFLATE)
4752 {
4753 destination->compression = COMPRESSION_DEFLATE;
4754 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4755 COMPRESSION_DEFLATE);
4756 }
4757 else if (tiff_compression == RL2_COMPRESSION_LZMA)
4758 {
4759 destination->compression = COMPRESSION_LZMA;
4760 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4761 COMPRESSION_LZMA);
4762 }
4763 else if (tiff_compression == RL2_COMPRESSION_JPEG)
4764 {
4765 destination->compression = COMPRESSION_JPEG;
4766 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4767 COMPRESSION_JPEG);
4768 }
4769 else
4770 {
4771 destination->compression = COMPRESSION_NONE;
4772 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4773 COMPRESSION_NONE);
4774 }
4775 goto header_done;
4776 }
4777 else if (pixel_type == RL2_PIXEL_DATAGRID)
4778 {
4779 /* GRID data */
4780 switch (sample_type)
4781 {
4782 case RL2_SAMPLE_INT8:
4783 case RL2_SAMPLE_INT16:
4784 case RL2_SAMPLE_INT32:
4785 destination->sampleFormat = SAMPLEFORMAT_INT;
4786 TIFFSetField (destination->out, TIFFTAG_SAMPLEFORMAT,
4787 SAMPLEFORMAT_INT);
4788 break;
4789 case RL2_SAMPLE_UINT8:
4790 case RL2_SAMPLE_UINT16:
4791 case RL2_SAMPLE_UINT32:
4792 destination->sampleFormat = SAMPLEFORMAT_UINT;
4793 TIFFSetField (destination->out, TIFFTAG_SAMPLEFORMAT,
4794 SAMPLEFORMAT_UINT);
4795 break;
4796 case RL2_SAMPLE_FLOAT:
4797 case RL2_SAMPLE_DOUBLE:
4798 destination->sampleFormat = SAMPLEFORMAT_IEEEFP;
4799 TIFFSetField (destination->out, TIFFTAG_SAMPLEFORMAT,
4800 SAMPLEFORMAT_IEEEFP);
4801 break;
4802 };
4803 destination->samplesPerPixel = 1;
4804 TIFFSetField (destination->out, TIFFTAG_SAMPLESPERPIXEL, 1);
4805 switch (sample_type)
4806 {
4807 case RL2_SAMPLE_INT8:
4808 case RL2_SAMPLE_UINT8:
4809 destination->bitsPerSample = 8;
4810 TIFFSetField (destination->out, TIFFTAG_BITSPERSAMPLE, 8);
4811 break;
4812 case RL2_SAMPLE_INT16:
4813 case RL2_SAMPLE_UINT16:
4814 destination->bitsPerSample = 16;
4815 TIFFSetField (destination->out, TIFFTAG_BITSPERSAMPLE, 16);
4816 break;
4817 case RL2_SAMPLE_INT32:
4818 case RL2_SAMPLE_UINT32:
4819 destination->bitsPerSample = 32;
4820 TIFFSetField (destination->out, TIFFTAG_BITSPERSAMPLE, 32);
4821 break;
4822 case RL2_SAMPLE_FLOAT:
4823 destination->bitsPerSample = 32;
4824 TIFFSetField (destination->out, TIFFTAG_BITSPERSAMPLE, 32);
4825 break;
4826 break;
4827 case RL2_SAMPLE_DOUBLE:
4828 destination->bitsPerSample = 64;
4829 TIFFSetField (destination->out, TIFFTAG_BITSPERSAMPLE, 64);
4830 break;
4831 }
4832 destination->photometric = PHOTOMETRIC_MINISBLACK;
4833 TIFFSetField (destination->out, TIFFTAG_PHOTOMETRIC,
4834 PHOTOMETRIC_MINISBLACK);
4835 if (tiff_compression == RL2_COMPRESSION_LZW)
4836 {
4837 destination->compression = COMPRESSION_LZW;
4838 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4839 COMPRESSION_LZW);
4840 }
4841 else if (tiff_compression == RL2_COMPRESSION_DEFLATE)
4842 {
4843 destination->compression = COMPRESSION_DEFLATE;
4844 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4845 COMPRESSION_DEFLATE);
4846 }
4847 else if (tiff_compression == RL2_COMPRESSION_LZMA)
4848 {
4849 destination->compression = COMPRESSION_LZMA;
4850 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4851 COMPRESSION_LZMA);
4852 }
4853 else
4854 {
4855 destination->compression = COMPRESSION_NONE;
4856 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4857 COMPRESSION_NONE);
4858 }
4859 }
4860 else if (pixel_type == RL2_PIXEL_MULTIBAND)
4861 {
4862 /* MULTIBAND */
4863 destination->sampleFormat = SAMPLEFORMAT_UINT;
4864 if (sample_type == RL2_SAMPLE_UINT8)
4865 destination->bitsPerSample = 8;
4866 else if (sample_type == RL2_SAMPLE_UINT16)
4867 destination->bitsPerSample = 16;
4868 else
4869 goto error;
4870 destination->samplesPerPixel = num_bands;
4871 if (num_bands == 2)
4872 destination->photometric = PHOTOMETRIC_MINISBLACK;
4873 else
4874 destination->photometric = PHOTOMETRIC_RGB;
4875 TIFFSetField (destination->out, TIFFTAG_SAMPLEFORMAT,
4876 SAMPLEFORMAT_UINT);
4877 TIFFSetField (destination->out, TIFFTAG_SAMPLESPERPIXEL,
4878 destination->samplesPerPixel);
4879 if (num_bands == 2)
4880 {
4881 uint16 extra[1];
4882 extra[0] = EXTRASAMPLE_UNSPECIFIED;
4883 TIFFSetField (destination->out, TIFFTAG_EXTRASAMPLES, 1,
4884 &extra);
4885 }
4886 if (num_bands > 3)
4887 {
4888 int n_extra = num_bands - 3;
4889 int i_extra;
4890 uint16 extra[256];
4891 for (i_extra = 0; i_extra < n_extra; i_extra++)
4892 extra[i_extra] = EXTRASAMPLE_UNSPECIFIED;
4893 TIFFSetField (destination->out, TIFFTAG_EXTRASAMPLES, n_extra,
4894 &extra);
4895 }
4896 TIFFSetField (destination->out, TIFFTAG_BITSPERSAMPLE,
4897 destination->bitsPerSample);
4898 TIFFSetField (destination->out, TIFFTAG_PHOTOMETRIC,
4899 destination->photometric);
4900 if (tiff_compression == RL2_COMPRESSION_LZW)
4901 {
4902 destination->compression = COMPRESSION_LZW;
4903 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4904 COMPRESSION_LZW);
4905 }
4906 else if (tiff_compression == RL2_COMPRESSION_DEFLATE)
4907 {
4908 destination->compression = COMPRESSION_DEFLATE;
4909 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4910 COMPRESSION_DEFLATE);
4911 }
4912 else if (tiff_compression == RL2_COMPRESSION_LZMA)
4913 {
4914 destination->compression = COMPRESSION_LZMA;
4915 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4916 COMPRESSION_LZMA);
4917 }
4918 else
4919 {
4920 destination->compression = COMPRESSION_NONE;
4921 TIFFSetField (destination->out, TIFFTAG_COMPRESSION,
4922 COMPRESSION_NONE);
4923 }
4924 goto header_done;
4925 }
4926 else
4927 goto error;
4928
4929 header_done:
4930 TIFFSetField (destination->out, TIFFTAG_SOFTWARE, "RasterLite-2");
4931 if (destination->isTiled)
4932 {
4933 TIFFSetField (destination->out, TIFFTAG_TILEWIDTH,
4934 destination->tileWidth);
4935 TIFFSetField (destination->out, TIFFTAG_TILELENGTH,
4936 destination->tileHeight);
4937 }
4938 else
4939 {
4940 if (tiff_compression == RL2_COMPRESSION_JPEG)
4941 TIFFSetField (destination->out, TIFFTAG_ROWSPERSTRIP, 8);
4942 else
4943 TIFFSetField (destination->out, TIFFTAG_ROWSPERSTRIP, 1);
4944 }
4945
4946 /* allocating the TIFF write buffer */
4947 if (destination->isTiled)
4948 buf_size = TIFFTileSize (destination->out);
4949 else
4950 buf_size = TIFFScanlineSize (destination->out);
4951 tiff_buffer = malloc (buf_size);
4952 if (!tiff_buffer)
4953 goto error;
4954 destination->tiffBuffer = tiff_buffer;
4955
4956 /* NULL georeferencing */
4957 destination->Srid = -1;
4958 destination->hResolution = DBL_MAX;
4959 destination->vResolution = DBL_MAX;
4960 destination->srsName = NULL;
4961 destination->proj4text = NULL;
4962 destination->minX = DBL_MAX;
4963 destination->minY = DBL_MAX;
4964 destination->maxX = DBL_MAX;
4965 destination->maxY = DBL_MAX;
4966 destination->tfw_path = NULL;
4967
4968 return 1;
4969 error:
4970 return 0;
4971 }
4972
4973 RL2_DECLARE rl2TiffDestinationPtr
rl2_create_tiff_destination(const char * path,unsigned int width,unsigned int height,unsigned char sample_type,unsigned char pixel_type,unsigned char num_bands,rl2PalettePtr plt,unsigned char tiff_compression,int tiled,unsigned int tile_size)4974 rl2_create_tiff_destination (const char *path, unsigned int width,
4975 unsigned int height, unsigned char sample_type,
4976 unsigned char pixel_type, unsigned char num_bands,
4977 rl2PalettePtr plt, unsigned char tiff_compression,
4978 int tiled, unsigned int tile_size)
4979 {
4980 /* attempting to create a file-based TIFF destination (no georeferencing) */
4981 rl2PrivTiffDestinationPtr destination = NULL;
4982 if (!check_color_model
4983 (sample_type, pixel_type, num_bands, plt, tiff_compression))
4984 {
4985 fprintf (stderr, "RL2-TIFF writer: unsupported pixel format\n");
4986 return NULL;
4987 }
4988
4989 destination = create_tiff_destination (path, 0);
4990 if (destination == NULL)
4991 return NULL;
4992
4993 destination->width = width;
4994 destination->height = height;
4995 if (tiled)
4996 {
4997 destination->isTiled = 1;
4998 destination->tileWidth = tile_size;
4999 destination->tileHeight = tile_size;
5000 }
5001 else
5002 {
5003 destination->isTiled = 0;
5004 destination->rowsPerStrip = 1;
5005 }
5006
5007 /* suppressing TIFF messages */
5008 TIFFSetErrorHandler (NULL);
5009 TIFFSetWarningHandler (NULL);
5010
5011 /* creating a TIFF file */
5012 destination->out = TIFFOpen (destination->path, "w");
5013 if (destination->out == NULL)
5014 goto error;
5015
5016 if (!set_tiff_destination
5017 (destination, width, height, sample_type, pixel_type, num_bands, plt,
5018 tiff_compression))
5019 goto error;
5020
5021 return (rl2TiffDestinationPtr) destination;
5022 error:
5023 if (destination != NULL)
5024 rl2_destroy_tiff_destination ((rl2TiffDestinationPtr) destination);
5025 return NULL;
5026 }
5027
5028 static int
is_projected_srs(const char * proj4text)5029 is_projected_srs (const char *proj4text)
5030 {
5031 /* checks if this one is a PCS SRS */
5032 if (proj4text == NULL)
5033 return 0;
5034 if (strstr (proj4text, "+proj=longlat ") != NULL)
5035 return 0;
5036 return 1;
5037 }
5038
5039 static void
fetch_crs_params(sqlite3 * handle,int srid,char ** srs_name,char ** proj4text)5040 fetch_crs_params (sqlite3 * handle, int srid, char **srs_name, char **proj4text)
5041 {
5042 int ret;
5043 char **results;
5044 int rows;
5045 int columns;
5046 int i;
5047 char *sql = sqlite3_mprintf ("SELECT ref_sys_name, proj4text "
5048 "FROM spatial_ref_sys WHERE srid = %d\n",
5049 srid);
5050 *srs_name = NULL;
5051 *proj4text = NULL;
5052 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
5053 sqlite3_free (sql);
5054 if (ret != SQLITE_OK)
5055 return;
5056 for (i = 1; i <= rows; i++)
5057 {
5058 int len;
5059 const char *name = results[(i * columns) + 0];
5060 const char *proj4 = results[(i * columns) + 1];
5061 if (name != NULL)
5062 {
5063 len = strlen (name);
5064 *srs_name = malloc (len + 1);
5065 strcpy (*srs_name, name);
5066 }
5067 if (proj4 != NULL)
5068 {
5069 len = strlen (proj4);
5070 *proj4text = malloc (len + 1);
5071 strcpy (*proj4text, proj4);
5072 }
5073 }
5074 sqlite3_free_table (results);
5075 }
5076
5077 static void
destination_set_tfw_path(const char * path,rl2PrivTiffDestinationPtr destination)5078 destination_set_tfw_path (const char *path,
5079 rl2PrivTiffDestinationPtr destination)
5080 {
5081 /* building the TFW path (WorldFile) */
5082 char *tfw;
5083 const char *x = NULL;
5084 const char *p = path;
5085 int len = strlen (path);
5086 len -= 1;
5087 while (*p != '\0')
5088 {
5089 if (*p == '.')
5090 x = p;
5091 p++;
5092 }
5093 if (x > path)
5094 len = x - path;
5095 tfw = malloc (len + 5);
5096 memcpy (tfw, path, len);
5097 memcpy (tfw + len, ".tfw", 4);
5098 *(tfw + len + 4) = '\0';
5099 destination->tfw_path = tfw;
5100 }
5101
5102 RL2_DECLARE rl2TiffDestinationPtr
rl2_create_geotiff_destination(const char * path,sqlite3 * handle,unsigned int width,unsigned int height,unsigned char sample_type,unsigned char pixel_type,unsigned char num_bands,rl2PalettePtr plt,unsigned char tiff_compression,int tiled,unsigned int tile_size,int srid,double minX,double minY,double maxX,double maxY,double hResolution,double vResolution,int with_worldfile)5103 rl2_create_geotiff_destination (const char *path, sqlite3 * handle,
5104 unsigned int width, unsigned int height,
5105 unsigned char sample_type,
5106 unsigned char pixel_type,
5107 unsigned char num_bands, rl2PalettePtr plt,
5108 unsigned char tiff_compression, int tiled,
5109 unsigned int tile_size, int srid, double minX,
5110 double minY, double maxX, double maxY,
5111 double hResolution, double vResolution,
5112 int with_worldfile)
5113 {
5114 /* attempting to create a file-based GeoTIFF destination */
5115 rl2PrivTiffDestinationPtr destination = NULL;
5116 double tiepoint[6];
5117 double pixsize[3];
5118 char *srs_name = NULL;
5119 char *proj4text = NULL;
5120 if (!check_color_model
5121 (sample_type, pixel_type, num_bands, plt, tiff_compression))
5122 {
5123 fprintf (stderr, "RL2-GeoTIFF writer: unsupported pixel format\n");
5124 return NULL;
5125 }
5126 if (handle == NULL)
5127 return NULL;
5128
5129 destination = create_tiff_destination (path, 1);
5130 if (destination == NULL)
5131 return NULL;
5132
5133 destination->width = width;
5134 destination->height = height;
5135 if (tiled)
5136 {
5137 destination->isTiled = 1;
5138 destination->tileWidth = tile_size;
5139 destination->tileHeight = tile_size;
5140 }
5141 else
5142 {
5143 destination->isTiled = 0;
5144 destination->rowsPerStrip = 1;
5145 }
5146
5147 /* suppressing TIFF messages */
5148 TIFFSetErrorHandler (NULL);
5149 TIFFSetWarningHandler (NULL);
5150
5151 /* creating a GeoTIFF file */
5152 destination->out = XTIFFOpen (destination->path, "w");
5153 if (destination->out == NULL)
5154 goto error;
5155 destination->gtif = GTIFNew (destination->out);
5156 if (destination->gtif == NULL)
5157 goto error;
5158
5159 if (!set_tiff_destination
5160 (destination, width, height, sample_type, pixel_type, num_bands, plt,
5161 tiff_compression))
5162 goto error;
5163
5164 /* attempting to retrieve the CRS params */
5165 fetch_crs_params (handle, srid, &srs_name, &proj4text);
5166 if (srs_name == NULL || proj4text == NULL)
5167 goto error;
5168
5169 /* setting georeferencing infos */
5170 destination->Srid = srid;
5171 destination->hResolution = hResolution;
5172 destination->vResolution = vResolution;
5173 destination->srsName = srs_name;
5174 destination->proj4text = proj4text;
5175 destination->minX = minX;
5176 destination->minY = minY;
5177 destination->maxX = maxX;
5178 destination->maxY = maxY;
5179 destination->tfw_path = NULL;
5180 if (with_worldfile)
5181 destination_set_tfw_path (path, destination);
5182
5183 /* setting up the GeoTIFF Tags */
5184 pixsize[0] = hResolution;
5185 pixsize[1] = vResolution;
5186 pixsize[2] = 0.0;
5187 TIFFSetField (destination->out, GTIFF_PIXELSCALE, 3, pixsize);
5188 tiepoint[0] = 0.0;
5189 tiepoint[1] = 0.0;
5190 tiepoint[2] = 0.0;
5191 tiepoint[3] = minX;
5192 tiepoint[4] = maxY;
5193 tiepoint[5] = 0.0;
5194 TIFFSetField (destination->out, GTIFF_TIEPOINTS, 6, tiepoint);
5195 if (srs_name != NULL)
5196 TIFFSetField (destination->out, GTIFF_ASCIIPARAMS, srs_name);
5197 if (proj4text != NULL)
5198 GTIFSetFromProj4 (destination->gtif, proj4text);
5199 if (srs_name != NULL)
5200 GTIFKeySet (destination->gtif, GTCitationGeoKey, TYPE_ASCII, 0,
5201 srs_name);
5202 if (is_projected_srs (proj4text))
5203 GTIFKeySet (destination->gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
5204 srid);
5205 GTIFWriteKeys (destination->gtif);
5206 destination->isGeoReferenced = 1;
5207
5208 return (rl2TiffDestinationPtr) destination;
5209 error:
5210 if (destination != NULL)
5211 rl2_destroy_tiff_destination ((rl2TiffDestinationPtr) destination);
5212 if (srs_name != NULL)
5213 free (srs_name);
5214 if (proj4text != NULL)
5215 free (proj4text);
5216 return NULL;
5217 }
5218
5219 RL2_DECLARE rl2TiffDestinationPtr
rl2_create_tiff_worldfile_destination(const char * path,unsigned int width,unsigned int height,unsigned char sample_type,unsigned char pixel_type,unsigned char num_bands,rl2PalettePtr plt,unsigned char tiff_compression,int tiled,unsigned int tile_size,int srid,double minX,double minY,double maxX,double maxY,double hResolution,double vResolution)5220 rl2_create_tiff_worldfile_destination (const char *path, unsigned int width,
5221 unsigned int height,
5222 unsigned char sample_type,
5223 unsigned char pixel_type,
5224 unsigned char num_bands,
5225 rl2PalettePtr plt,
5226 unsigned char tiff_compression,
5227 int tiled, unsigned int tile_size,
5228 int srid, double minX, double minY,
5229 double maxX, double maxY,
5230 double hResolution, double vResolution)
5231 {
5232 /* attempting to create a file-based TIFF destination (with worldfile) */
5233 rl2TiffDestinationPtr destination =
5234 rl2_create_tiff_destination (path, width, height, sample_type,
5235 pixel_type, num_bands,
5236 plt, tiff_compression, tiled, tile_size);
5237 rl2PrivTiffDestinationPtr tiff = (rl2PrivTiffDestinationPtr) destination;
5238 if (tiff == NULL)
5239 return NULL;
5240 /* setting georeferencing infos */
5241 tiff->Srid = srid;
5242 tiff->hResolution = hResolution;
5243 tiff->vResolution = vResolution;
5244 tiff->srsName = NULL;
5245 tiff->proj4text = NULL;
5246 tiff->minX = minX;
5247 tiff->minY = minY;
5248 tiff->maxX = maxX;
5249 tiff->maxY = maxY;
5250 tiff->tfw_path = NULL;
5251 destination_set_tfw_path (path, tiff);
5252 tiff->isGeoReferenced = 1;
5253 return destination;
5254 }
5255
5256 RL2_DECLARE const char *
rl2_get_tiff_destination_path(rl2TiffDestinationPtr tiff)5257 rl2_get_tiff_destination_path (rl2TiffDestinationPtr tiff)
5258 {
5259 /* retrieving the output path from a TIFF destination */
5260 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5261 if (destination == NULL)
5262 return NULL;
5263
5264 return destination->path;
5265 }
5266
5267 RL2_DECLARE const char *
rl2_get_tiff_destination_worldfile_path(rl2TiffDestinationPtr tiff)5268 rl2_get_tiff_destination_worldfile_path (rl2TiffDestinationPtr tiff)
5269 {
5270 /* retrieving the Worldfile path from a TIFF destination */
5271 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5272 if (destination == NULL)
5273 return NULL;
5274
5275 return destination->tfw_path;
5276 }
5277
5278 RL2_DECLARE int
rl2_is_geotiff_destination(rl2TiffDestinationPtr tiff,int * geotiff)5279 rl2_is_geotiff_destination (rl2TiffDestinationPtr tiff, int *geotiff)
5280 {
5281 /* detecting if a TIFF destination actually is a GeoTIFF */
5282 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5283 if (destination == NULL)
5284 return RL2_ERROR;
5285 *geotiff = destination->isGeoTiff;
5286 return RL2_OK;
5287 }
5288
5289 RL2_DECLARE int
rl2_is_tiff_worldfile_destination(rl2TiffDestinationPtr tiff,int * tiff_worldfile)5290 rl2_is_tiff_worldfile_destination (rl2TiffDestinationPtr tiff,
5291 int *tiff_worldfile)
5292 {
5293 /* detecting if a TIFF destination actually supports a TFW */
5294 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5295 if (destination == NULL)
5296 return RL2_ERROR;
5297 *tiff_worldfile = 0;
5298 if (destination->tfw_path != NULL)
5299 *tiff_worldfile = 1;
5300 return RL2_OK;
5301 }
5302
5303 RL2_DECLARE int
rl2_get_tiff_destination_size(rl2TiffDestinationPtr tiff,unsigned int * width,unsigned int * height)5304 rl2_get_tiff_destination_size (rl2TiffDestinationPtr tiff,
5305 unsigned int *width, unsigned int *height)
5306 {
5307 /* retrieving Width and Height from a TIFF destination */
5308 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5309 if (destination == NULL)
5310 return RL2_ERROR;
5311
5312 *width = destination->width;
5313 *height = destination->height;
5314 return RL2_OK;
5315 }
5316
5317 RL2_DECLARE int
rl2_get_tiff_destination_srid(rl2TiffDestinationPtr tiff,int * srid)5318 rl2_get_tiff_destination_srid (rl2TiffDestinationPtr tiff, int *srid)
5319 {
5320 /* retrieving the SRID from a TIFF destination */
5321 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5322 if (destination == NULL)
5323 return RL2_ERROR;
5324 if (destination->isGeoReferenced == 0)
5325 return RL2_ERROR;
5326
5327 *srid = destination->Srid;
5328 return RL2_OK;
5329 }
5330
5331 RL2_DECLARE int
rl2_get_tiff_destination_extent(rl2TiffDestinationPtr tiff,double * minX,double * minY,double * maxX,double * maxY)5332 rl2_get_tiff_destination_extent (rl2TiffDestinationPtr tiff, double *minX,
5333 double *minY, double *maxX, double *maxY)
5334 {
5335 /* retrieving the Extent from a TIFF destination */
5336 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5337 if (destination == NULL)
5338 return RL2_ERROR;
5339 if (destination->isGeoReferenced == 0)
5340 return RL2_ERROR;
5341
5342 *minX = destination->minX;
5343 *minY = destination->minY;
5344 *maxX = destination->maxX;
5345 *maxY = destination->maxY;
5346 return RL2_OK;
5347 }
5348
5349 RL2_DECLARE int
rl2_get_tiff_destination_resolution(rl2TiffDestinationPtr tiff,double * hResolution,double * vResolution)5350 rl2_get_tiff_destination_resolution (rl2TiffDestinationPtr tiff,
5351 double *hResolution, double *vResolution)
5352 {
5353 /* retrieving the Pixel Resolution from a TIFF destination */
5354 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5355 if (destination == NULL)
5356 return RL2_ERROR;
5357 if (destination->isGeoReferenced == 0)
5358 return RL2_ERROR;
5359
5360 *hResolution = destination->hResolution;
5361 *vResolution = destination->vResolution;
5362 return RL2_OK;
5363 }
5364
5365 RL2_DECLARE int
rl2_get_tiff_destination_type(rl2TiffDestinationPtr tiff,unsigned char * sample_type,unsigned char * pixel_type,unsigned char * alias_pixel_type,unsigned char * num_bands)5366 rl2_get_tiff_destination_type (rl2TiffDestinationPtr tiff,
5367 unsigned char *sample_type,
5368 unsigned char *pixel_type,
5369 unsigned char *alias_pixel_type,
5370 unsigned char *num_bands)
5371 {
5372 /* retrieving the sample/pixel type from a TIFF destination */
5373 int ok = 0;
5374 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5375 if (destination == NULL)
5376 return RL2_ERROR;
5377
5378 if (destination->sampleFormat == SAMPLEFORMAT_UINT
5379 && destination->samplesPerPixel == 1
5380 && destination->photometric < PHOTOMETRIC_RGB)
5381 {
5382 /* could be some kind of MONOCHROME */
5383 if (destination->bitsPerSample == 1)
5384 {
5385 *sample_type = RL2_SAMPLE_1_BIT;
5386 ok = 1;
5387 }
5388 if (ok)
5389 {
5390 *pixel_type = RL2_PIXEL_MONOCHROME;
5391 *alias_pixel_type = RL2_PIXEL_MONOCHROME;
5392 *num_bands = 1;
5393 return RL2_OK;
5394 }
5395 }
5396 if (destination->sampleFormat == SAMPLEFORMAT_UINT
5397 && destination->samplesPerPixel == 1
5398 && destination->photometric < PHOTOMETRIC_RGB)
5399 {
5400 /* could be some kind of GRAYSCALE */
5401 if (destination->bitsPerSample == 2)
5402 {
5403 *sample_type = RL2_SAMPLE_2_BIT;
5404 ok = 1;
5405 }
5406 else if (destination->bitsPerSample == 4)
5407 {
5408 *sample_type = RL2_SAMPLE_4_BIT;
5409 ok = 1;
5410 }
5411 else if (destination->bitsPerSample == 8)
5412 {
5413 *sample_type = RL2_SAMPLE_UINT8;
5414 ok = 1;
5415 }
5416 else if (destination->bitsPerSample == 16)
5417 {
5418 *sample_type = RL2_SAMPLE_UINT16;
5419 ok = 1;
5420 }
5421 if (ok)
5422 {
5423 *pixel_type = RL2_PIXEL_GRAYSCALE;
5424 *alias_pixel_type = RL2_PIXEL_GRAYSCALE;
5425 if (destination->bitsPerSample == 8
5426 || destination->bitsPerSample == 16)
5427 *alias_pixel_type = RL2_PIXEL_DATAGRID;
5428 *num_bands = 1;
5429 return RL2_OK;
5430 }
5431 }
5432 if (destination->sampleFormat == SAMPLEFORMAT_UINT
5433 && destination->samplesPerPixel == 1
5434 && destination->photometric == PHOTOMETRIC_PALETTE)
5435 {
5436 /* could be some kind of PALETTE */
5437 if (destination->bitsPerSample == 1)
5438 {
5439 *sample_type = RL2_SAMPLE_1_BIT;
5440 ok = 1;
5441 }
5442 else if (destination->bitsPerSample == 2)
5443 {
5444 *sample_type = RL2_SAMPLE_2_BIT;
5445 ok = 1;
5446 }
5447 else if (destination->bitsPerSample == 4)
5448 {
5449 *sample_type = RL2_SAMPLE_4_BIT;
5450 ok = 1;
5451 }
5452 else if (destination->bitsPerSample == 8)
5453 {
5454 *sample_type = RL2_SAMPLE_UINT8;
5455 ok = 1;
5456 }
5457 if (ok)
5458 {
5459 *pixel_type = RL2_PIXEL_PALETTE;
5460 *alias_pixel_type = RL2_PIXEL_PALETTE;
5461 *num_bands = 1;
5462 return RL2_OK;
5463 }
5464 }
5465 if (destination->sampleFormat == SAMPLEFORMAT_UINT
5466 && destination->samplesPerPixel == 3
5467 && destination->photometric == PHOTOMETRIC_RGB)
5468 {
5469 /* could be some kind of RGB */
5470 if (destination->bitsPerSample == 8)
5471 {
5472 *sample_type = RL2_SAMPLE_UINT8;
5473 ok = 1;
5474 }
5475 else if (destination->bitsPerSample == 16)
5476 {
5477 *sample_type = RL2_SAMPLE_UINT16;
5478 ok = 1;
5479 }
5480 if (ok)
5481 {
5482 *pixel_type = RL2_PIXEL_RGB;
5483 *alias_pixel_type = RL2_PIXEL_RGB;
5484 *num_bands = 3;
5485 return RL2_OK;
5486 }
5487 }
5488 if (destination->samplesPerPixel == 1
5489 && destination->photometric < PHOTOMETRIC_RGB)
5490 {
5491 /* could be some kind of DATA-GRID */
5492 if (destination->sampleFormat == SAMPLEFORMAT_INT)
5493 {
5494 /* Signed Integer */
5495 if (destination->bitsPerSample == 8)
5496 {
5497 *sample_type = RL2_SAMPLE_INT8;
5498 ok = 1;
5499 }
5500 else if (destination->bitsPerSample == 16)
5501 {
5502 *sample_type = RL2_SAMPLE_INT16;
5503 ok = 1;
5504 }
5505 else if (destination->bitsPerSample == 32)
5506 {
5507 *sample_type = RL2_SAMPLE_INT32;
5508 ok = 1;
5509 }
5510 }
5511 if (destination->sampleFormat == SAMPLEFORMAT_UINT)
5512 {
5513 /* Unsigned Integer */
5514 if (destination->bitsPerSample == 8)
5515 {
5516 *sample_type = RL2_SAMPLE_UINT8;
5517 ok = 1;
5518 }
5519 else if (destination->bitsPerSample == 16)
5520 {
5521 *sample_type = RL2_SAMPLE_UINT16;
5522 ok = 1;
5523 }
5524 else if (destination->bitsPerSample == 32)
5525 {
5526 *sample_type = RL2_SAMPLE_UINT32;
5527 ok = 1;
5528 }
5529 }
5530 if (destination->sampleFormat == SAMPLEFORMAT_IEEEFP)
5531 {
5532 /* Floating-Point */
5533 if (destination->bitsPerSample == 32)
5534 {
5535 *sample_type = RL2_SAMPLE_FLOAT;
5536 ok = 1;
5537 }
5538 else if (destination->bitsPerSample == 64)
5539 {
5540 *sample_type = RL2_SAMPLE_DOUBLE;
5541 ok = 1;
5542 }
5543 }
5544 if (ok)
5545 {
5546 *pixel_type = RL2_PIXEL_DATAGRID;
5547 *alias_pixel_type = RL2_PIXEL_DATAGRID;
5548 *num_bands = 1;
5549 return RL2_OK;
5550 }
5551 }
5552 return RL2_ERROR;
5553 }
5554
5555 RL2_DECLARE int
rl2_get_tiff_destination_compression(rl2TiffDestinationPtr tiff,unsigned char * compression)5556 rl2_get_tiff_destination_compression (rl2TiffDestinationPtr tiff,
5557 unsigned char *compression)
5558 {
5559 /* retrieving the sample/pixel type from a TIFF destination */
5560 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5561 if (destination == NULL)
5562 return RL2_ERROR;
5563
5564 switch (destination->compression)
5565 {
5566 case COMPRESSION_NONE:
5567 *compression = RL2_COMPRESSION_NONE;
5568 break;
5569 case COMPRESSION_LZW:
5570 *compression = RL2_COMPRESSION_LZW;
5571 break;
5572 case COMPRESSION_DEFLATE:
5573 *compression = RL2_COMPRESSION_DEFLATE;
5574 break;
5575 case COMPRESSION_LZMA:
5576 *compression = RL2_COMPRESSION_LZMA;
5577 break;
5578 case COMPRESSION_JPEG:
5579 *compression = RL2_COMPRESSION_JPEG;
5580 break;
5581 case COMPRESSION_CCITTFAX3:
5582 *compression = RL2_COMPRESSION_CCITTFAX3;
5583 break;
5584 case COMPRESSION_CCITTFAX4:
5585 *compression = RL2_COMPRESSION_CCITTFAX4;
5586 break;
5587 default:
5588 *compression = RL2_COMPRESSION_UNKNOWN;
5589 break;
5590 }
5591 return RL2_OK;
5592 }
5593
5594 RL2_DECLARE int
rl2_is_tiled_tiff_destination(rl2TiffDestinationPtr tiff,int * is_tiled)5595 rl2_is_tiled_tiff_destination (rl2TiffDestinationPtr tiff, int *is_tiled)
5596 {
5597 /* testing if the TIFF Destination is tiled or not */
5598 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5599 if (destination == NULL)
5600 return RL2_ERROR;
5601 *is_tiled = destination->isTiled;
5602 return RL2_OK;
5603 }
5604
5605 RL2_DECLARE int
rl2_get_tiff_destination_tile_size(rl2TiffDestinationPtr tiff,unsigned int * tile_width,unsigned int * tile_height)5606 rl2_get_tiff_destination_tile_size (rl2TiffDestinationPtr tiff,
5607 unsigned int *tile_width,
5608 unsigned int *tile_height)
5609 {
5610 /* attempting to return the Tile dimensions */
5611 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5612 if (destination == NULL)
5613 return RL2_ERROR;
5614 if (destination->isTiled == 0)
5615 return RL2_ERROR;
5616 *tile_width = destination->tileWidth;
5617 *tile_height = destination->tileHeight;
5618 return RL2_OK;
5619 }
5620
5621 RL2_DECLARE int
rl2_get_tiff_destination_strip_size(rl2TiffDestinationPtr tiff,unsigned int * strip_size)5622 rl2_get_tiff_destination_strip_size (rl2TiffDestinationPtr tiff,
5623 unsigned int *strip_size)
5624 {
5625 /* attempting to return the Strip dimension */
5626 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5627 if (destination == NULL)
5628 return RL2_ERROR;
5629 if (destination->isTiled != 0)
5630 return RL2_ERROR;
5631 *strip_size = destination->rowsPerStrip;
5632 return RL2_OK;
5633 }
5634
5635 static int
tiff_write_strip_rgb(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5636 tiff_write_strip_rgb (rl2PrivTiffDestinationPtr tiff, rl2PrivRasterPtr raster,
5637 unsigned int row)
5638 {
5639 /* writing a TIFF RGB scanline */
5640 unsigned int x;
5641 unsigned char *p_in = raster->rasterBuffer;
5642 unsigned char *p_out = tiff->tiffBuffer;
5643
5644 for (x = 0; x < raster->width; x++)
5645 {
5646 *p_out++ = *p_in++;
5647 *p_out++ = *p_in++;
5648 *p_out++ = *p_in++;
5649 if (raster->nBands == 4)
5650 p_in++;
5651 }
5652 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5653 return 0;
5654 return 1;
5655 }
5656
5657 static int
tiff_write_strip_gray(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5658 tiff_write_strip_gray (rl2PrivTiffDestinationPtr tiff, rl2PrivRasterPtr raster,
5659 unsigned int row)
5660 {
5661 /* writing a TIFF Grayscale scanline */
5662 unsigned int x;
5663 unsigned char *p_in = raster->rasterBuffer;
5664 unsigned char *p_out = tiff->tiffBuffer;
5665
5666 for (x = 0; x < raster->width; x++)
5667 *p_out++ = *p_in++;
5668 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5669 return 0;
5670 return 1;
5671 }
5672
5673 static int
tiff_write_strip_palette(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5674 tiff_write_strip_palette (rl2PrivTiffDestinationPtr tiff,
5675 rl2PrivRasterPtr raster, unsigned int row)
5676 {
5677 /* writing a TIFF Palette scanline */
5678 unsigned int x;
5679 unsigned char *p_in = raster->rasterBuffer;
5680 unsigned char *p_out = tiff->tiffBuffer;
5681
5682 for (x = 0; x < raster->width; x++)
5683 *p_out++ = *p_in++;
5684 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5685 return 0;
5686 return 1;
5687 }
5688
5689 static int
tiff_write_strip_monochrome(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5690 tiff_write_strip_monochrome (rl2PrivTiffDestinationPtr tiff,
5691 rl2PrivRasterPtr raster, unsigned int row)
5692 {
5693 /* writing a TIFF Monochrome */
5694 unsigned int x;
5695 unsigned char byte;
5696 unsigned char pixel;
5697 int pos;
5698 unsigned char *p_in = raster->rasterBuffer;
5699 unsigned char *p_out = tiff->tiffBuffer;
5700
5701 /* priming a White scanline */
5702 for (x = 0; x < TIFFScanlineSize (tiff->out); x++)
5703 *p_out++ = 0x00;
5704
5705 /* inserting pixels */
5706 pos = 0;
5707 byte = 0x00;
5708 p_out = tiff->tiffBuffer;
5709 for (x = 0; x < raster->width; x++)
5710 {
5711 pixel = *p_in++;
5712 if (pixel == 1)
5713 {
5714 /* handling a black pixel */
5715 switch (pos)
5716 {
5717 case 0:
5718 byte |= 0x80;
5719 break;
5720 case 1:
5721 byte |= 0x40;
5722 break;
5723 case 2:
5724 byte |= 0x20;
5725 break;
5726 case 3:
5727 byte |= 0x10;
5728 break;
5729 case 4:
5730 byte |= 0x08;
5731 break;
5732 case 5:
5733 byte |= 0x04;
5734 break;
5735 case 6:
5736 byte |= 0x02;
5737 break;
5738 case 7:
5739 byte |= 0x01;
5740 break;
5741 };
5742 }
5743 pos++;
5744 if (pos > 7)
5745 {
5746 /* exporting an octet */
5747 *p_out++ = byte;
5748 byte = 0x00;
5749 pos = 0;
5750 }
5751 }
5752 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5753 return 0;
5754 return 1;
5755 }
5756
5757 static int
tiff_write_strip_int8(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5758 tiff_write_strip_int8 (rl2PrivTiffDestinationPtr tiff,
5759 rl2PrivRasterPtr raster, unsigned int row)
5760 {
5761 /* writing a TIFF Grid Int8 scanline */
5762 unsigned int x;
5763 char *p_in = (char *) (raster->rasterBuffer);
5764 char *p_out = (char *) (tiff->tiffBuffer);
5765
5766 for (x = 0; x < raster->width; x++)
5767 *p_out++ = *p_in++;
5768 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5769 return 0;
5770 return 1;
5771 }
5772
5773 static int
tiff_write_strip_uint8(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5774 tiff_write_strip_uint8 (rl2PrivTiffDestinationPtr tiff,
5775 rl2PrivRasterPtr raster, unsigned int row)
5776 {
5777 /* writing a TIFF Grid UInt8 scanline */
5778 unsigned int x;
5779 unsigned char *p_in = raster->rasterBuffer;
5780 unsigned char *p_out = tiff->tiffBuffer;
5781
5782 for (x = 0; x < raster->width; x++)
5783 *p_out++ = *p_in++;
5784 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5785 return 0;
5786 return 1;
5787 }
5788
5789 static int
tiff_write_strip_int16(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5790 tiff_write_strip_int16 (rl2PrivTiffDestinationPtr tiff,
5791 rl2PrivRasterPtr raster, unsigned int row)
5792 {
5793 /* writing a TIFF Grid Int16 scanline */
5794 unsigned int x;
5795 short *p_in = (short *) (raster->rasterBuffer);
5796 short *p_out = (short *) (tiff->tiffBuffer);
5797
5798 for (x = 0; x < raster->width; x++)
5799 *p_out++ = *p_in++;
5800 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5801 return 0;
5802 return 1;
5803 }
5804
5805 static int
tiff_write_strip_uint16(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5806 tiff_write_strip_uint16 (rl2PrivTiffDestinationPtr tiff,
5807 rl2PrivRasterPtr raster, unsigned int row)
5808 {
5809 /* writing a TIFF Grid UInt16 scanline */
5810 unsigned int x;
5811 unsigned short *p_in = (unsigned short *) (raster->rasterBuffer);
5812 unsigned short *p_out = (unsigned short *) (tiff->tiffBuffer);
5813
5814 for (x = 0; x < raster->width; x++)
5815 *p_out++ = *p_in++;
5816 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5817 return 0;
5818 return 1;
5819 }
5820
5821 static int
tiff_write_strip_int32(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5822 tiff_write_strip_int32 (rl2PrivTiffDestinationPtr tiff,
5823 rl2PrivRasterPtr raster, unsigned int row)
5824 {
5825 /* writing a TIFF Grid Int32 scanline */
5826 unsigned int x;
5827 int *p_in = (int *) (raster->rasterBuffer);
5828 int *p_out = (int *) (tiff->tiffBuffer);
5829
5830 for (x = 0; x < raster->width; x++)
5831 *p_out++ = *p_in++;
5832 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5833 return 0;
5834 return 1;
5835 }
5836
5837 static int
tiff_write_strip_uint32(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5838 tiff_write_strip_uint32 (rl2PrivTiffDestinationPtr tiff,
5839 rl2PrivRasterPtr raster, unsigned int row)
5840 {
5841 /* writing a TIFF Grid UInt32 scanline */
5842 unsigned int x;
5843 unsigned int *p_in = (unsigned int *) (raster->rasterBuffer);
5844 unsigned int *p_out = (unsigned int *) (tiff->tiffBuffer);
5845
5846 for (x = 0; x < raster->width; x++)
5847 *p_out++ = *p_in++;
5848 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5849 return 0;
5850 return 1;
5851 }
5852
5853 static int
tiff_write_strip_float(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5854 tiff_write_strip_float (rl2PrivTiffDestinationPtr tiff,
5855 rl2PrivRasterPtr raster, unsigned int row)
5856 {
5857 /* writing a TIFF Grid Float scanline */
5858 unsigned int x;
5859 float *p_in = (float *) (raster->rasterBuffer);
5860 float *p_out = (float *) (tiff->tiffBuffer);
5861
5862 for (x = 0; x < raster->width; x++)
5863 *p_out++ = *p_in++;
5864 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5865 return 0;
5866 return 1;
5867 }
5868
5869 static int
tiff_write_strip_double(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row)5870 tiff_write_strip_double (rl2PrivTiffDestinationPtr tiff,
5871 rl2PrivRasterPtr raster, unsigned int row)
5872 {
5873 /* writing a TIFF Grid Double scanline */
5874 unsigned int x;
5875 double *p_in = (double *) (raster->rasterBuffer);
5876 double *p_out = (double *) (tiff->tiffBuffer);
5877
5878 for (x = 0; x < raster->width; x++)
5879 *p_out++ = *p_in++;
5880 if (TIFFWriteScanline (tiff->out, tiff->tiffBuffer, row, 0) < 0)
5881 return 0;
5882 return 1;
5883 }
5884
5885 RL2_DECLARE int
rl2_write_tiff_scanline(rl2TiffDestinationPtr tiff,rl2RasterPtr raster,unsigned int row)5886 rl2_write_tiff_scanline (rl2TiffDestinationPtr tiff, rl2RasterPtr raster,
5887 unsigned int row)
5888 {
5889 /* writing a TIFF scanline */
5890 int ret = 0;
5891 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
5892 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) raster;
5893 if (tiff == NULL)
5894 return RL2_ERROR;
5895 if (rst == NULL)
5896 return RL2_ERROR;
5897
5898 if (destination->sampleFormat == SAMPLEFORMAT_UINT
5899 && destination->samplesPerPixel == 3 && destination->photometric == 2
5900 && destination->bitsPerSample == 8
5901 && rst->sampleType == RL2_SAMPLE_UINT8
5902 && rst->pixelType == RL2_PIXEL_RGB && (rst->nBands == 3
5903 || rst->nBands == 4)
5904 && destination->width == rst->width)
5905 ret = tiff_write_strip_rgb (destination, rst, row);
5906 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
5907 && destination->samplesPerPixel == 1
5908 && destination->photometric < 2
5909 && destination->bitsPerSample == 8
5910 && rst->sampleType == RL2_SAMPLE_UINT8
5911 && rst->pixelType == RL2_PIXEL_GRAYSCALE && rst->nBands == 1
5912 && destination->width == rst->width)
5913 ret = tiff_write_strip_gray (destination, rst, row);
5914 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
5915 && destination->samplesPerPixel == 1
5916 && destination->photometric == 3
5917 && destination->bitsPerSample == 8
5918 && rst->sampleType == RL2_SAMPLE_UINT8
5919 && rst->pixelType == RL2_PIXEL_PALETTE && rst->nBands == 1
5920 && destination->width == rst->width)
5921 ret = tiff_write_strip_palette (destination, rst, row);
5922 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
5923 && destination->samplesPerPixel == 1
5924 && destination->photometric < 2
5925 && destination->bitsPerSample == 1
5926 && rst->sampleType == RL2_SAMPLE_1_BIT
5927 && rst->pixelType == RL2_PIXEL_MONOCHROME && rst->nBands == 1
5928 && destination->width == rst->width)
5929 ret = tiff_write_strip_monochrome (destination, rst, row);
5930 else if (destination->sampleFormat == SAMPLEFORMAT_INT
5931 && destination->samplesPerPixel == 1
5932 && destination->photometric < 2
5933 && destination->bitsPerSample == 8
5934 && rst->sampleType == RL2_SAMPLE_INT8
5935 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
5936 && destination->width == rst->width)
5937 ret = tiff_write_strip_int8 (destination, rst, row);
5938 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
5939 && destination->samplesPerPixel == 1
5940 && destination->photometric < 2
5941 && destination->bitsPerSample == 8
5942 && rst->sampleType == RL2_SAMPLE_UINT8
5943 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
5944 && destination->width == rst->width)
5945 ret = tiff_write_strip_uint8 (destination, rst, row);
5946 else if (destination->sampleFormat == SAMPLEFORMAT_INT
5947 && destination->samplesPerPixel == 1
5948 && destination->photometric < 2
5949 && destination->bitsPerSample == 16
5950 && rst->sampleType == RL2_SAMPLE_INT16
5951 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
5952 && destination->width == rst->width)
5953 ret = tiff_write_strip_int16 (destination, rst, row);
5954 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
5955 && destination->samplesPerPixel == 1
5956 && destination->photometric < 2
5957 && destination->bitsPerSample == 16
5958 && rst->sampleType == RL2_SAMPLE_UINT16
5959 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
5960 && destination->width == rst->width)
5961 ret = tiff_write_strip_uint16 (destination, rst, row);
5962 else if (destination->sampleFormat == SAMPLEFORMAT_INT
5963 && destination->samplesPerPixel == 1
5964 && destination->photometric < 2
5965 && destination->bitsPerSample == 32
5966 && rst->sampleType == RL2_SAMPLE_INT32
5967 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
5968 && destination->width == rst->width)
5969 ret = tiff_write_strip_int32 (destination, rst, row);
5970 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
5971 && destination->samplesPerPixel == 1
5972 && destination->photometric < 2
5973 && destination->bitsPerSample == 32
5974 && rst->sampleType == RL2_SAMPLE_UINT32
5975 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
5976 && destination->width == rst->width)
5977 ret = tiff_write_strip_uint32 (destination, rst, row);
5978 else if (destination->sampleFormat == SAMPLEFORMAT_IEEEFP
5979 && destination->samplesPerPixel == 1
5980 && destination->photometric < 2
5981 && destination->bitsPerSample == 32
5982 && rst->sampleType == RL2_SAMPLE_FLOAT
5983 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
5984 && destination->width == rst->width)
5985 ret = tiff_write_strip_float (destination, rst, row);
5986 else if (destination->sampleFormat == SAMPLEFORMAT_IEEEFP
5987 && destination->samplesPerPixel == 1
5988 && destination->photometric < 2
5989 && destination->bitsPerSample == 64
5990 && rst->sampleType == RL2_SAMPLE_DOUBLE
5991 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
5992 && destination->width == rst->width)
5993 ret = tiff_write_strip_double (destination, rst, row);
5994
5995 if (ret)
5996 return RL2_OK;
5997 return RL2_ERROR;
5998 }
5999
6000 static int
tiff_write_tile_multiband8(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6001 tiff_write_tile_multiband8 (rl2PrivTiffDestinationPtr tiff,
6002 rl2PrivRasterPtr raster, unsigned int row,
6003 unsigned int col)
6004 {
6005 /* writing a TIFF MULTIBAND UINT8 tile - separate planes */
6006 unsigned int y;
6007 unsigned int x;
6008 int band;
6009
6010 for (band = 0; band < raster->nBands; band++)
6011 {
6012 /* handling separate planes - one for each band */
6013 unsigned char *p_in = raster->rasterBuffer;
6014 unsigned char *p_out = tiff->tiffBuffer;
6015 for (y = 0; y < raster->height; y++)
6016 {
6017 for (x = 0; x < raster->width; x++)
6018 {
6019 *p_out++ = *(p_in + band);
6020 p_in += raster->nBands;
6021 }
6022 }
6023 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, band) <
6024 0)
6025 return 0;
6026 }
6027 return 1;
6028 }
6029
6030 static int
tiff_write_tile_multiband16(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6031 tiff_write_tile_multiband16 (rl2PrivTiffDestinationPtr tiff,
6032 rl2PrivRasterPtr raster, unsigned int row,
6033 unsigned int col)
6034 {
6035 /* writing a TIFF MULTIBAND UINT16 tile - separate planes */
6036 unsigned int y;
6037 unsigned int x;
6038 int band;
6039
6040 for (band = 0; band < raster->nBands; band++)
6041 {
6042 /* handling separate planes - one for each band */
6043 unsigned short *p_in = (unsigned short *) (raster->rasterBuffer);
6044 unsigned short *p_out = (unsigned short *) (tiff->tiffBuffer);
6045 for (y = 0; y < raster->height; y++)
6046 {
6047 for (x = 0; x < raster->width; x++)
6048 {
6049 *p_out++ = *(p_in + band);
6050 p_in += raster->nBands;
6051 }
6052 }
6053 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, band) <
6054 0)
6055 return 0;
6056 }
6057 return 1;
6058 }
6059
6060 static int
tiff_write_tile_rgb_u8(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6061 tiff_write_tile_rgb_u8 (rl2PrivTiffDestinationPtr tiff, rl2PrivRasterPtr raster,
6062 unsigned int row, unsigned int col)
6063 {
6064 /* writing a TIFF RGB tile - UINT8 */
6065 unsigned int y;
6066 unsigned int x;
6067 unsigned char *p_in = raster->rasterBuffer;
6068 unsigned char *p_out = tiff->tiffBuffer;
6069
6070 for (y = 0; y < raster->height; y++)
6071 {
6072 for (x = 0; x < raster->width; x++)
6073 {
6074 *p_out++ = *p_in++;
6075 *p_out++ = *p_in++;
6076 *p_out++ = *p_in++;
6077 if (raster->nBands == 4)
6078 p_in++;
6079 }
6080 }
6081 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6082 return 0;
6083 return 1;
6084 }
6085
6086 static int
tiff_write_tile_gray(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6087 tiff_write_tile_gray (rl2PrivTiffDestinationPtr tiff, rl2PrivRasterPtr raster,
6088 unsigned int row, unsigned int col)
6089 {
6090 /* writing a TIFF Grayscale tile */
6091 unsigned int y;
6092 unsigned int x;
6093 unsigned char *p_in = raster->rasterBuffer;
6094 unsigned char *p_msk = raster->maskBuffer;
6095 unsigned char *p_out = tiff->tiffBuffer;
6096
6097 for (y = 0; y < raster->height; y++)
6098 {
6099 for (x = 0; x < raster->width; x++)
6100 {
6101 if (p_msk == NULL)
6102 {
6103 /* there is no Transparency Mask - all opaque pixels */
6104 *p_out++ = *p_in++;
6105 }
6106 else
6107 {
6108 if (*p_msk++ == 0)
6109 {
6110 /* transparent pixel */
6111 p_out++;
6112 }
6113 else
6114 *p_out++ = *p_in++;
6115 }
6116 }
6117 }
6118 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6119 return 0;
6120 return 1;
6121 }
6122
6123 static int
tiff_write_tile_palette(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6124 tiff_write_tile_palette (rl2PrivTiffDestinationPtr tiff,
6125 rl2PrivRasterPtr raster, unsigned int row,
6126 unsigned int col)
6127 {
6128 /* writing a TIFF Palette tile */
6129 unsigned int y;
6130 unsigned int x;
6131 unsigned char *p_in = raster->rasterBuffer;
6132 unsigned char *p_out = tiff->tiffBuffer;
6133
6134 for (y = 0; y < raster->height; y++)
6135 {
6136 for (x = 0; x < raster->width; x++)
6137 *p_out++ = *p_in++;
6138 }
6139 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6140 return 0;
6141 return 1;
6142 }
6143
6144 static int
tiff_write_tile_monochrome(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6145 tiff_write_tile_monochrome (rl2PrivTiffDestinationPtr tiff,
6146 rl2PrivRasterPtr raster, unsigned int row,
6147 unsigned int col)
6148 {
6149 /* writing a TIFF Monochrome tile */
6150 unsigned int y;
6151 unsigned int x;
6152 unsigned char byte;
6153 unsigned char pixel;
6154 int pos;
6155 unsigned char *p_in = raster->rasterBuffer;
6156 unsigned char *p_out = tiff->tiffBuffer;
6157
6158 /* priming a White tile */
6159 for (x = 0; x < TIFFTileSize (tiff->out); x++)
6160 *p_out++ = 0x00;
6161 p_out = tiff->tiffBuffer;
6162 for (y = 0; y < raster->height; y++)
6163 {
6164 /* inserting pixels */
6165 pos = 0;
6166 byte = 0x00;
6167 for (x = 0; x < raster->width; x++)
6168 {
6169 pixel = *p_in++;
6170 if (pixel == 1)
6171 {
6172 /* handling a black pixel */
6173 switch (pos)
6174 {
6175 case 0:
6176 byte |= 0x80;
6177 break;
6178 case 1:
6179 byte |= 0x40;
6180 break;
6181 case 2:
6182 byte |= 0x20;
6183 break;
6184 case 3:
6185 byte |= 0x10;
6186 break;
6187 case 4:
6188 byte |= 0x08;
6189 break;
6190 case 5:
6191 byte |= 0x04;
6192 break;
6193 case 6:
6194 byte |= 0x02;
6195 break;
6196 case 7:
6197 byte |= 0x01;
6198 break;
6199 };
6200 }
6201 pos++;
6202 if (pos > 7)
6203 {
6204 /* exporting an octet */
6205 *p_out++ = byte;
6206 byte = 0x00;
6207 pos = 0;
6208 }
6209 }
6210 }
6211 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6212 return 0;
6213 return 1;
6214 }
6215
6216 static int
tiff_write_tile_int8(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6217 tiff_write_tile_int8 (rl2PrivTiffDestinationPtr tiff,
6218 rl2PrivRasterPtr raster, unsigned int row,
6219 unsigned int col)
6220 {
6221 /* writing a TIFF Grid Int8 tile */
6222 unsigned int y;
6223 unsigned int x;
6224 char *p_in = (char *) (raster->rasterBuffer);
6225 char *p_out = (char *) (tiff->tiffBuffer);
6226
6227 for (y = 0; y < raster->height; y++)
6228 {
6229 for (x = 0; x < raster->width; x++)
6230 *p_out++ = *p_in++;
6231 }
6232 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6233 return 0;
6234 return 1;
6235 }
6236
6237 static int
tiff_write_tile_uint8(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6238 tiff_write_tile_uint8 (rl2PrivTiffDestinationPtr tiff,
6239 rl2PrivRasterPtr raster, unsigned int row,
6240 unsigned int col)
6241 {
6242 /* writing a TIFF Grid UInt8 tile */
6243 unsigned int y;
6244 unsigned int x;
6245 unsigned char *p_in = raster->rasterBuffer;
6246 unsigned char *p_out = tiff->tiffBuffer;
6247
6248 for (y = 0; y < raster->height; y++)
6249 {
6250 for (x = 0; x < raster->width; x++)
6251 *p_out++ = *p_in++;
6252 }
6253 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6254 return 0;
6255 return 1;
6256 }
6257
6258 static int
tiff_write_tile_int16(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6259 tiff_write_tile_int16 (rl2PrivTiffDestinationPtr tiff,
6260 rl2PrivRasterPtr raster, unsigned int row,
6261 unsigned int col)
6262 {
6263 /* writing a TIFF Grid Int16 tile */
6264 unsigned int y;
6265 unsigned int x;
6266 short *p_in = (short *) (raster->rasterBuffer);
6267 short *p_out = (short *) (tiff->tiffBuffer);
6268
6269 for (y = 0; y < raster->height; y++)
6270 {
6271 for (x = 0; x < raster->width; x++)
6272 *p_out++ = *p_in++;
6273 }
6274 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6275 return 0;
6276 return 1;
6277 }
6278
6279 static int
tiff_write_tile_uint16(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6280 tiff_write_tile_uint16 (rl2PrivTiffDestinationPtr tiff,
6281 rl2PrivRasterPtr raster, unsigned int row,
6282 unsigned int col)
6283 {
6284 /* writing a TIFF Grid UInt16 tile */
6285 unsigned int y;
6286 unsigned int x;
6287 unsigned short *p_in = (unsigned short *) (raster->rasterBuffer);
6288 unsigned short *p_out = (unsigned short *) (tiff->tiffBuffer);
6289
6290 for (y = 0; y < raster->height; y++)
6291 {
6292 for (x = 0; x < raster->width; x++)
6293 *p_out++ = *p_in++;
6294 }
6295 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6296 return 0;
6297 return 1;
6298 }
6299
6300 static int
tiff_write_tile_int32(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6301 tiff_write_tile_int32 (rl2PrivTiffDestinationPtr tiff,
6302 rl2PrivRasterPtr raster, unsigned int row,
6303 unsigned int col)
6304 {
6305 /* writing a TIFF Grid Int32 tile */
6306 unsigned int y;
6307 unsigned int x;
6308 int *p_in = (int *) (raster->rasterBuffer);
6309 int *p_out = (int *) (tiff->tiffBuffer);
6310
6311 for (y = 0; y < raster->height; y++)
6312 {
6313 for (x = 0; x < raster->width; x++)
6314 *p_out++ = *p_in++;
6315 }
6316 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6317 return 0;
6318 return 1;
6319 }
6320
6321 static int
tiff_write_tile_uint32(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6322 tiff_write_tile_uint32 (rl2PrivTiffDestinationPtr tiff,
6323 rl2PrivRasterPtr raster, unsigned int row,
6324 unsigned int col)
6325 {
6326 /* writing a TIFF Grid UInt32 tile */
6327 unsigned int y;
6328 unsigned int x;
6329 unsigned int *p_in = (unsigned int *) (raster->rasterBuffer);
6330 unsigned int *p_out = (unsigned int *) (tiff->tiffBuffer);
6331
6332 for (y = 0; y < raster->height; y++)
6333 {
6334 for (x = 0; x < raster->width; x++)
6335 *p_out++ = *p_in++;
6336 }
6337 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6338 return 0;
6339 return 1;
6340 }
6341
6342 static int
tiff_write_tile_float(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6343 tiff_write_tile_float (rl2PrivTiffDestinationPtr tiff,
6344 rl2PrivRasterPtr raster, unsigned int row,
6345 unsigned int col)
6346 {
6347 /* writing a TIFF Grid Float tile */
6348 unsigned int y;
6349 unsigned int x;
6350 float *p_in = (float *) (raster->rasterBuffer);
6351 float *p_out = (float *) (tiff->tiffBuffer);
6352
6353 for (y = 0; y < raster->height; y++)
6354 {
6355 for (x = 0; x < raster->width; x++)
6356 *p_out++ = *p_in++;
6357 }
6358 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6359 return 0;
6360 return 1;
6361 }
6362
6363 static int
tiff_write_tile_double(rl2PrivTiffDestinationPtr tiff,rl2PrivRasterPtr raster,unsigned int row,unsigned int col)6364 tiff_write_tile_double (rl2PrivTiffDestinationPtr tiff,
6365 rl2PrivRasterPtr raster, unsigned int row,
6366 unsigned int col)
6367 {
6368 /* writing a TIFF Grid Double tile */
6369 unsigned int y;
6370 unsigned int x;
6371 double *p_in = (double *) (raster->rasterBuffer);
6372 double *p_out = (double *) (tiff->tiffBuffer);
6373
6374 for (y = 0; y < raster->height; y++)
6375 {
6376 for (x = 0; x < raster->width; x++)
6377 *p_out++ = *p_in++;
6378 }
6379 if (TIFFWriteTile (tiff->out, tiff->tiffBuffer, col, row, 0, 0) < 0)
6380 return 0;
6381 return 1;
6382 }
6383
6384 RL2_DECLARE int
rl2_write_tiff_tile(rl2TiffDestinationPtr tiff,rl2RasterPtr raster,unsigned int startRow,unsigned int startCol)6385 rl2_write_tiff_tile (rl2TiffDestinationPtr tiff, rl2RasterPtr raster,
6386 unsigned int startRow, unsigned int startCol)
6387 {
6388 /* writing a TIFF tile */
6389 int ret = 0;
6390 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
6391 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) raster;
6392 if (tiff == NULL)
6393 return RL2_ERROR;
6394 if (rst == NULL)
6395 return RL2_ERROR;
6396
6397 if (destination->sampleFormat == SAMPLEFORMAT_UINT
6398 && destination->samplesPerPixel == 3 && destination->photometric == 2
6399 && destination->bitsPerSample == 8
6400 && rst->sampleType == RL2_SAMPLE_UINT8
6401 && rst->pixelType == RL2_PIXEL_RGB && (rst->nBands == 3
6402 || rst->nBands == 4)
6403 && destination->tileWidth == rst->width
6404 && destination->tileHeight == rst->height)
6405 ret = tiff_write_tile_rgb_u8 (destination, rst, startRow, startCol);
6406 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
6407 && destination->samplesPerPixel == 3
6408 && destination->photometric == 2
6409 && destination->bitsPerSample == 16
6410 && rst->sampleType == RL2_SAMPLE_UINT16
6411 && rst->pixelType == RL2_PIXEL_RGB && rst->nBands == 3
6412 && destination->tileWidth == rst->width
6413 && destination->tileHeight == rst->height)
6414 ret =
6415 tiff_write_tile_multiband16 (destination, rst, startRow, startCol);
6416 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
6417 && destination->samplesPerPixel >= 2
6418 && destination->bitsPerSample == 8
6419 && rst->sampleType == RL2_SAMPLE_UINT8
6420 && rst->pixelType == RL2_PIXEL_MULTIBAND
6421 && rst->nBands == destination->samplesPerPixel
6422 && destination->tileWidth == rst->width
6423 && destination->tileHeight == rst->height)
6424 ret = tiff_write_tile_multiband8 (destination, rst, startRow, startCol);
6425 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
6426 && destination->samplesPerPixel >= 2
6427 && destination->bitsPerSample == 16
6428 && rst->sampleType == RL2_SAMPLE_UINT16
6429 && rst->pixelType == RL2_PIXEL_MULTIBAND
6430 && rst->nBands == destination->samplesPerPixel
6431 && destination->tileWidth == rst->width
6432 && destination->tileHeight == rst->height)
6433 ret =
6434 tiff_write_tile_multiband16 (destination, rst, startRow, startCol);
6435 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
6436 && destination->samplesPerPixel == 1
6437 && destination->photometric < 2 && destination->bitsPerSample == 8
6438 && rst->sampleType == RL2_SAMPLE_UINT8
6439 && rst->pixelType == RL2_PIXEL_GRAYSCALE && rst->nBands == 1
6440 && destination->tileWidth == rst->width
6441 && destination->tileHeight == rst->height)
6442 ret = tiff_write_tile_gray (destination, rst, startRow, startCol);
6443 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
6444 && destination->samplesPerPixel == 1
6445 && destination->photometric == 3
6446 && destination->bitsPerSample == 8
6447 && (rst->sampleType == RL2_SAMPLE_UINT8
6448 || rst->sampleType == RL2_SAMPLE_1_BIT
6449 || rst->sampleType == RL2_SAMPLE_2_BIT
6450 || rst->sampleType == RL2_SAMPLE_4_BIT)
6451 && rst->pixelType == RL2_PIXEL_PALETTE && rst->nBands == 1
6452 && destination->tileWidth == rst->width
6453 && destination->tileHeight == rst->height)
6454 ret = tiff_write_tile_palette (destination, rst, startRow, startCol);
6455 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
6456 && destination->samplesPerPixel == 1
6457 && destination->photometric < 2
6458 && destination->bitsPerSample == 1
6459 && rst->sampleType == RL2_SAMPLE_1_BIT
6460 && rst->pixelType == RL2_PIXEL_MONOCHROME && rst->nBands == 1
6461 && destination->tileWidth == rst->width
6462 && destination->tileHeight == rst->height)
6463 ret = tiff_write_tile_monochrome (destination, rst, startRow, startCol);
6464 else if (destination->sampleFormat == SAMPLEFORMAT_INT
6465 && destination->samplesPerPixel == 1
6466 && destination->photometric < 2
6467 && destination->bitsPerSample == 8
6468 && rst->sampleType == RL2_SAMPLE_INT8
6469 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
6470 && destination->tileWidth == rst->width
6471 && destination->tileHeight == rst->height)
6472 ret = tiff_write_tile_int8 (destination, rst, startRow, startCol);
6473 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
6474 && destination->samplesPerPixel == 1
6475 && destination->photometric < 2
6476 && destination->bitsPerSample == 8
6477 && rst->sampleType == RL2_SAMPLE_UINT8
6478 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
6479 && destination->tileWidth == rst->width
6480 && destination->tileHeight == rst->height)
6481 ret = tiff_write_tile_uint8 (destination, rst, startRow, startCol);
6482 else if (destination->sampleFormat == SAMPLEFORMAT_INT
6483 && destination->samplesPerPixel == 1
6484 && destination->photometric < 2
6485 && destination->bitsPerSample == 16
6486 && rst->sampleType == RL2_SAMPLE_INT16
6487 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
6488 && destination->tileWidth == rst->width
6489 && destination->tileHeight == rst->height)
6490 ret = tiff_write_tile_int16 (destination, rst, startRow, startCol);
6491 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
6492 && destination->samplesPerPixel == 1
6493 && destination->photometric < 2
6494 && destination->bitsPerSample == 16
6495 && rst->sampleType == RL2_SAMPLE_UINT16
6496 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
6497 && destination->tileWidth == rst->width
6498 && destination->tileHeight == rst->height)
6499 ret = tiff_write_tile_uint16 (destination, rst, startRow, startCol);
6500 else if (destination->sampleFormat == SAMPLEFORMAT_INT
6501 && destination->samplesPerPixel == 1
6502 && destination->photometric < 2
6503 && destination->bitsPerSample == 32
6504 && rst->sampleType == RL2_SAMPLE_INT32
6505 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
6506 && destination->tileWidth == rst->width
6507 && destination->tileHeight == rst->height)
6508 ret = tiff_write_tile_int32 (destination, rst, startRow, startCol);
6509 else if (destination->sampleFormat == SAMPLEFORMAT_UINT
6510 && destination->samplesPerPixel == 1
6511 && destination->photometric < 2
6512 && destination->bitsPerSample == 32
6513 && rst->sampleType == RL2_SAMPLE_UINT32
6514 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
6515 && destination->tileWidth == rst->width
6516 && destination->tileHeight == rst->height)
6517 ret = tiff_write_tile_uint32 (destination, rst, startRow, startCol);
6518 else if (destination->sampleFormat == SAMPLEFORMAT_IEEEFP
6519 && destination->samplesPerPixel == 1
6520 && destination->photometric < 2
6521 && destination->bitsPerSample == 32
6522 && rst->sampleType == RL2_SAMPLE_FLOAT
6523 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
6524 && destination->tileWidth == rst->width
6525 && destination->tileHeight == rst->height)
6526 ret = tiff_write_tile_float (destination, rst, startRow, startCol);
6527 else if (destination->sampleFormat == SAMPLEFORMAT_IEEEFP
6528 && destination->samplesPerPixel == 1
6529 && destination->photometric < 2
6530 && destination->bitsPerSample == 64
6531 && rst->sampleType == RL2_SAMPLE_DOUBLE
6532 && rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1
6533 && destination->tileWidth == rst->width
6534 && destination->tileHeight == rst->height)
6535 ret = tiff_write_tile_double (destination, rst, startRow, startCol);
6536
6537 if (ret)
6538 return RL2_OK;
6539 return RL2_ERROR;
6540 }
6541
6542 RL2_DECLARE int
rl2_write_tiff_worldfile(rl2TiffDestinationPtr tiff)6543 rl2_write_tiff_worldfile (rl2TiffDestinationPtr tiff)
6544 {
6545 /* writing a Worldfile supporting a TIFF destination */
6546 FILE *tfw;
6547 rl2PrivTiffDestinationPtr destination = (rl2PrivTiffDestinationPtr) tiff;
6548 if (destination == NULL)
6549 return RL2_ERROR;
6550 if (destination->tfw_path == NULL)
6551 return RL2_ERROR;
6552
6553 tfw = fopen (destination->tfw_path, "w");
6554 if (tfw == NULL)
6555 {
6556 fprintf (stderr, "RL2-TIFF writer: unable to open Worldfile \"%s\"\n",
6557 destination->tfw_path);
6558 return RL2_ERROR;
6559 }
6560 fprintf (tfw, " %1.16f\n", destination->hResolution);
6561 fprintf (tfw, " 0.0\n");
6562 fprintf (tfw, " 0.0\n");
6563 fprintf (tfw, " -%1.16f\n", destination->vResolution);
6564 fprintf (tfw, " %1.16f\n", destination->minX);
6565 fprintf (tfw, " %1.16f\n", destination->maxY);
6566 fclose (tfw);
6567 return RL2_OK;
6568 }
6569
6570 static int
compress_fax4(const unsigned char * buffer,unsigned short width,unsigned short height,unsigned char ** blob,int * blob_size)6571 compress_fax4 (const unsigned char *buffer,
6572 unsigned short width,
6573 unsigned short height, unsigned char **blob, int *blob_size)
6574 {
6575 /* compressing a TIFF FAX4 block - actual work */
6576 struct memfile clientdata;
6577 TIFF *out = (TIFF *) 0;
6578 tsize_t buf_size;
6579 void *tiff_buffer = NULL;
6580 int y;
6581 int x;
6582 unsigned char byte;
6583 unsigned char pixel;
6584 int pos;
6585 const unsigned char *p_in;
6586 unsigned char *p_out;
6587
6588 /* suppressing TIFF warnings */
6589 TIFFSetWarningHandler (NULL);
6590
6591 /* writing into memory */
6592 clientdata.buffer = NULL;
6593 clientdata.malloc_block = 1024;
6594 clientdata.size = 0;
6595 clientdata.eof = 0;
6596 clientdata.current = 0;
6597 out = TIFFClientOpen ("tiff", "w", &clientdata, memory_readproc,
6598 memory_writeproc, memory_seekproc, closeproc,
6599 memory_sizeproc, mapproc, unmapproc);
6600 if (out == NULL)
6601 return 0;
6602
6603 /* setting up the TIFF headers */
6604 TIFFSetField (out, TIFFTAG_SUBFILETYPE, 0);
6605 TIFFSetField (out, TIFFTAG_IMAGEWIDTH, width);
6606 TIFFSetField (out, TIFFTAG_IMAGELENGTH, height);
6607 TIFFSetField (out, TIFFTAG_XRESOLUTION, 300.0);
6608 TIFFSetField (out, TIFFTAG_YRESOLUTION, 300.0);
6609 TIFFSetField (out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
6610 TIFFSetField (out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
6611 TIFFSetField (out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
6612 TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
6613 TIFFSetField (out, TIFFTAG_SAMPLESPERPIXEL, 1);
6614 TIFFSetField (out, TIFFTAG_BITSPERSAMPLE, 1);
6615 TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
6616 TIFFSetField (out, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
6617 TIFFSetField (out, TIFFTAG_TILEWIDTH, width);
6618 TIFFSetField (out, TIFFTAG_TILELENGTH, height);
6619
6620 /* allocating the TIFF write buffer */
6621 buf_size = TIFFTileSize (out);
6622 tiff_buffer = malloc (buf_size);
6623 if (tiff_buffer == NULL)
6624 goto error;
6625
6626 /* writing a TIFF Monochrome tile */
6627 p_in = buffer;
6628 p_out = tiff_buffer;
6629
6630 /* priming a White tile */
6631 for (x = 0; x < buf_size; x++)
6632 *p_out++ = 0x00;
6633 p_out = tiff_buffer;
6634 for (y = 0; y < height; y++)
6635 {
6636 /* inserting pixels */
6637 pos = 0;
6638 byte = 0x00;
6639 for (x = 0; x < width; x++)
6640 {
6641 pixel = *p_in++;
6642 if (pixel == 1)
6643 {
6644 /* handling a black pixel */
6645 switch (pos)
6646 {
6647 case 0:
6648 byte |= 0x80;
6649 break;
6650 case 1:
6651 byte |= 0x40;
6652 break;
6653 case 2:
6654 byte |= 0x20;
6655 break;
6656 case 3:
6657 byte |= 0x10;
6658 break;
6659 case 4:
6660 byte |= 0x08;
6661 break;
6662 case 5:
6663 byte |= 0x04;
6664 break;
6665 case 6:
6666 byte |= 0x02;
6667 break;
6668 case 7:
6669 byte |= 0x01;
6670 break;
6671 };
6672 }
6673 pos++;
6674 if (pos > 7)
6675 {
6676 /* exporting an octet */
6677 *p_out++ = byte;
6678 byte = 0x00;
6679 pos = 0;
6680 }
6681 }
6682 }
6683 if (TIFFWriteTile (out, tiff_buffer, 0, 0, 0, 0) < 0)
6684 goto error;
6685
6686 TIFFClose (out);
6687 free (tiff_buffer);
6688 *blob = clientdata.buffer;
6689 *blob_size = clientdata.eof;
6690 return 1;
6691
6692 error:
6693 TIFFClose (out);
6694 if (tiff_buffer != NULL)
6695 free (tiff_buffer);
6696 if (clientdata.buffer != NULL)
6697 free (clientdata.buffer);
6698 return 0;
6699 }
6700
6701 RL2_DECLARE int
rl2_raster_to_tiff_mono4(rl2RasterPtr rst,unsigned char ** tiff,int * tiff_size)6702 rl2_raster_to_tiff_mono4 (rl2RasterPtr rst, unsigned char **tiff,
6703 int *tiff_size)
6704 {
6705 /* creating a TIFF FAX4 block from a raster */
6706 rl2PrivRasterPtr raster = (rl2PrivRasterPtr) rst;
6707 unsigned char sample_type;
6708 unsigned char pixel_type;
6709 unsigned char num_samples;
6710 if (rst == NULL)
6711 return RL2_ERROR;
6712 if (rl2_get_raster_type (rst, &sample_type, &pixel_type, &num_samples) !=
6713 RL2_OK)
6714 return RL2_ERROR;
6715 if (sample_type == RL2_SAMPLE_1_BIT && pixel_type == RL2_PIXEL_MONOCHROME
6716 && num_samples == 1)
6717 ;
6718 else
6719 return RL2_ERROR;
6720
6721 if (!compress_fax4 (raster->rasterBuffer, raster->width,
6722 raster->height, tiff, tiff_size))
6723 return RL2_ERROR;
6724 return RL2_OK;
6725 }
6726
6727 RL2_PRIVATE int
rl2_decode_tiff_mono4(const unsigned char * tiff,int tiff_sz,unsigned int * xwidth,unsigned int * xheight,unsigned char ** pixels,int * pixels_sz)6728 rl2_decode_tiff_mono4 (const unsigned char *tiff, int tiff_sz,
6729 unsigned int *xwidth, unsigned int *xheight,
6730 unsigned char **pixels, int *pixels_sz)
6731 {
6732 /* attempting to decode a TIFF FAX4 block */
6733 struct memfile clientdata;
6734 TIFF *in = (TIFF *) 0;
6735 int is_tiled;
6736 uint32 width = 0;
6737 uint32 height = 0;
6738 uint32 tile_width;
6739 uint32 tile_height;
6740 uint16 bits_per_sample;
6741 uint16 samples_per_pixel;
6742 uint16 photometric;
6743 uint16 compression;
6744 uint16 sample_format;
6745 uint16 planar_config;
6746 tsize_t buf_size;
6747 void *tiff_buffer = NULL;
6748 unsigned int x;
6749 unsigned char pixel;
6750 unsigned char *buffer;
6751 int buf_sz;
6752 const unsigned char *p_in;
6753 unsigned char *p_out;
6754
6755 /* suppressing TIFF warnings */
6756 TIFFSetWarningHandler (NULL);
6757
6758 /* reading from memory */
6759 clientdata.buffer = (unsigned char *) tiff;
6760 clientdata.malloc_block = 1024;
6761 clientdata.size = tiff_sz;
6762 clientdata.eof = tiff_sz;
6763 clientdata.current = 0;
6764 in = TIFFClientOpen ("tiff", "r", &clientdata, memory_readproc,
6765 memory_writeproc, memory_seekproc, closeproc,
6766 memory_sizeproc, mapproc, unmapproc);
6767 if (in == NULL)
6768 return RL2_ERROR;
6769
6770 /* retrieving the TIFF dimensions */
6771 is_tiled = TIFFIsTiled (in);
6772 if (!is_tiled)
6773 goto error;
6774 TIFFGetField (in, TIFFTAG_IMAGELENGTH, &height);
6775 TIFFGetField (in, TIFFTAG_IMAGEWIDTH, &width);
6776 TIFFGetField (in, TIFFTAG_TILEWIDTH, &tile_width);
6777 TIFFGetField (in, TIFFTAG_TILELENGTH, &tile_height);
6778 if (tile_width != width)
6779 goto error;
6780 if (tile_height != height)
6781 goto error;
6782 TIFFGetField (in, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
6783 if (bits_per_sample != 1)
6784 goto error;
6785 TIFFGetField (in, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
6786 if (samples_per_pixel != 1)
6787 goto error;
6788 TIFFGetField (in, TIFFTAG_SAMPLEFORMAT, &sample_format);
6789 if (sample_format != SAMPLEFORMAT_UINT)
6790 goto error;
6791 TIFFGetField (in, TIFFTAG_PLANARCONFIG, &planar_config);
6792 if (planar_config != PLANARCONFIG_CONTIG)
6793 goto error;
6794 TIFFGetField (in, TIFFTAG_PHOTOMETRIC, &photometric);
6795 if (photometric != PHOTOMETRIC_MINISWHITE)
6796 goto error;
6797 TIFFGetField (in, TIFFTAG_COMPRESSION, &compression);
6798 if (compression != COMPRESSION_CCITTFAX4)
6799 goto error;
6800
6801 /* allocating the tile buffer */
6802 buf_size = TIFFTileSize (in);
6803 tiff_buffer = malloc (buf_size);
6804 if (tiff_buffer == NULL)
6805 goto error;
6806
6807 /* reading and decoding as a single tile */
6808 if (!TIFFReadTile (in, tiff_buffer, 0, 0, 0, 0))
6809 goto error;
6810
6811 /* allocating the output buffer */
6812 buf_sz = width * height;
6813 buffer = malloc (buf_sz);
6814 if (buffer == NULL)
6815 goto error;
6816
6817 p_in = tiff_buffer;
6818 p_out = buffer;
6819 for (x = 0; x < buf_size; x++)
6820 {
6821 pixel = *p_in++;
6822 if ((pixel & 0x80) == 0x80)
6823 *p_out++ = 1;
6824 else
6825 *p_out++ = 0;
6826 if ((pixel & 0x40) == 0x40)
6827 *p_out++ = 1;
6828 else
6829 *p_out++ = 0;
6830 if ((pixel & 0x20) == 0x20)
6831 *p_out++ = 1;
6832 else
6833 *p_out++ = 0;
6834 if ((pixel & 0x10) == 0x10)
6835 *p_out++ = 1;
6836 else
6837 *p_out++ = 0;
6838 if ((pixel & 0x08) == 0x08)
6839 *p_out++ = 1;
6840 else
6841 *p_out++ = 0;
6842 if ((pixel & 0x04) == 0x04)
6843 *p_out++ = 1;
6844 else
6845 *p_out++ = 0;
6846 if ((pixel & 0x02) == 0x02)
6847 *p_out++ = 1;
6848 else
6849 *p_out++ = 0;
6850 if ((pixel & 0x01) == 0x01)
6851 *p_out++ = 1;
6852 else
6853 *p_out++ = 0;
6854 }
6855
6856 TIFFClose (in);
6857 if (tiff_buffer != NULL)
6858 free (tiff_buffer);
6859 *xwidth = width;
6860 *xheight = height;
6861 *pixels = buffer;
6862 *pixels_sz = buf_sz;
6863 return RL2_OK;
6864
6865 error:
6866 TIFFClose (in);
6867 if (tiff_buffer != NULL)
6868 free (tiff_buffer);
6869 return RL2_ERROR;
6870 }
6871
6872 static int
rgb_tiff_common(TIFF * out,const unsigned char * buffer,unsigned short width,unsigned short height)6873 rgb_tiff_common (TIFF * out, const unsigned char *buffer, unsigned short width,
6874 unsigned short height)
6875 {
6876 /* common implementation of RGB TIFF export */
6877 tsize_t buf_size;
6878 void *tiff_buffer = NULL;
6879 int y;
6880 int x;
6881 const unsigned char *p_in;
6882 unsigned char *p_out;
6883
6884 /* setting up the TIFF headers */
6885 TIFFSetField (out, TIFFTAG_SUBFILETYPE, 0);
6886 TIFFSetField (out, TIFFTAG_IMAGEWIDTH, width);
6887 TIFFSetField (out, TIFFTAG_IMAGELENGTH, height);
6888 TIFFSetField (out, TIFFTAG_XRESOLUTION, 300.0);
6889 TIFFSetField (out, TIFFTAG_YRESOLUTION, 300.0);
6890 TIFFSetField (out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
6891 TIFFSetField (out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
6892 TIFFSetField (out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
6893 TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
6894 TIFFSetField (out, TIFFTAG_SAMPLESPERPIXEL, 3);
6895 TIFFSetField (out, TIFFTAG_BITSPERSAMPLE, 8);
6896 TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
6897 TIFFSetField (out, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
6898 TIFFSetField (out, TIFFTAG_ROWSPERSTRIP, 1);
6899
6900 /* allocating the TIFF write buffer */
6901 buf_size = TIFFScanlineSize (out);
6902 tiff_buffer = malloc (buf_size);
6903 if (tiff_buffer == NULL)
6904 goto error;
6905
6906 /* writing TIFF RGB scanlines */
6907 p_in = buffer;
6908
6909 for (y = 0; y < height; y++)
6910 {
6911 /* inserting pixels */
6912 p_out = tiff_buffer;
6913 for (x = 0; x < width; x++)
6914 {
6915 *p_out++ = *p_in++; /* red */
6916 *p_out++ = *p_in++; /* green */
6917 *p_out++ = *p_in++; /* blue */
6918 }
6919 if (TIFFWriteScanline (out, tiff_buffer, y, 0) < 0)
6920 goto error;
6921 }
6922
6923 free (tiff_buffer);
6924 return 1;
6925 error:
6926 if (tiff_buffer != NULL)
6927 free (tiff_buffer);
6928 return 0;
6929 }
6930
6931 static int
output_rgb_tiff(const unsigned char * buffer,unsigned short width,unsigned short height,unsigned char ** blob,int * blob_size)6932 output_rgb_tiff (const unsigned char *buffer,
6933 unsigned short width,
6934 unsigned short height, unsigned char **blob, int *blob_size)
6935 {
6936 /* generating an RGB TIFF - actual work */
6937 struct memfile clientdata;
6938 TIFF *out = (TIFF *) 0;
6939
6940 /* suppressing TIFF warnings */
6941 TIFFSetWarningHandler (NULL);
6942
6943 /* writing into memory */
6944 clientdata.buffer = NULL;
6945 clientdata.malloc_block = 1024;
6946 clientdata.size = 0;
6947 clientdata.eof = 0;
6948 clientdata.current = 0;
6949 out = TIFFClientOpen ("tiff", "w", &clientdata, memory_readproc,
6950 memory_writeproc, memory_seekproc, closeproc,
6951 memory_sizeproc, mapproc, unmapproc);
6952 if (out == NULL)
6953 return 0;
6954
6955 if (!rgb_tiff_common (out, buffer, width, height))
6956 goto error;
6957
6958 TIFFClose (out);
6959 *blob = clientdata.buffer;
6960 *blob_size = clientdata.eof;
6961 return 1;
6962
6963 error:
6964 TIFFClose (out);
6965 if (clientdata.buffer != NULL)
6966 free (clientdata.buffer);
6967 return 0;
6968 }
6969
6970 static int
output_rgb_geotiff(const unsigned char * buffer,unsigned short width,unsigned short height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,unsigned char ** blob,int * blob_size)6971 output_rgb_geotiff (const unsigned char *buffer,
6972 unsigned short width,
6973 unsigned short height, sqlite3 * handle, double minx,
6974 double miny, double maxx, double maxy, int srid,
6975 unsigned char **blob, int *blob_size)
6976 {
6977 /* generating an RGB TIFF - actual work */
6978 struct memfile clientdata;
6979 double tiepoint[6];
6980 double pixsize[3];
6981 double hResolution = (maxx - minx) / (double) width;
6982 double vResolution = (maxy - miny) / (double) height;
6983 char *srs_name = NULL;
6984 char *proj4text = NULL;
6985 GTIF *gtif = (GTIF *) 0;
6986 TIFF *out = (TIFF *) 0;
6987
6988 /* suppressing TIFF warnings */
6989 TIFFSetWarningHandler (NULL);
6990
6991 /* writing into memory */
6992 clientdata.buffer = NULL;
6993 clientdata.malloc_block = 1024;
6994 clientdata.size = 0;
6995 clientdata.eof = 0;
6996 clientdata.current = 0;
6997
6998 out = XTIFFClientOpen ("tiff", "w", &clientdata, memory_readproc,
6999 memory_writeproc, memory_seekproc, closeproc,
7000 memory_sizeproc, mapproc, unmapproc);
7001 if (out == NULL)
7002 goto error;
7003 gtif = GTIFNew (out);
7004 if (gtif == NULL)
7005 goto error;
7006
7007 /* attempting to retrieve the CRS params */
7008 fetch_crs_params (handle, srid, &srs_name, &proj4text);
7009 if (srs_name == NULL || proj4text == NULL)
7010 goto error;
7011
7012 /* setting up the GeoTIFF Tags */
7013 pixsize[0] = hResolution;
7014 pixsize[1] = vResolution;
7015 pixsize[2] = 0.0;
7016 TIFFSetField (out, GTIFF_PIXELSCALE, 3, pixsize);
7017 tiepoint[0] = 0.0;
7018 tiepoint[1] = 0.0;
7019 tiepoint[2] = 0.0;
7020 tiepoint[3] = minx;
7021 tiepoint[4] = maxy;
7022 tiepoint[5] = 0.0;
7023 TIFFSetField (out, GTIFF_TIEPOINTS, 6, tiepoint);
7024 if (srs_name != NULL)
7025 TIFFSetField (out, GTIFF_ASCIIPARAMS, srs_name);
7026 if (proj4text != NULL)
7027 GTIFSetFromProj4 (gtif, proj4text);
7028 if (srs_name != NULL)
7029 GTIFKeySet (gtif, GTCitationGeoKey, TYPE_ASCII, 0, srs_name);
7030 if (is_projected_srs (proj4text))
7031 GTIFKeySet (gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, srid);
7032 GTIFWriteKeys (gtif);
7033
7034 if (!rgb_tiff_common (out, buffer, width, height))
7035 goto error;
7036
7037 GTIFFree (gtif);
7038 XTIFFClose (out);
7039 *blob = clientdata.buffer;
7040 *blob_size = clientdata.eof;
7041 if (srs_name != NULL)
7042 free (srs_name);
7043 if (proj4text != NULL)
7044 free (proj4text);
7045 return 1;
7046
7047 error:
7048 if (gtif != (GTIF *) 0)
7049 GTIFFree (gtif);
7050 if (out != (TIFF *) 0)
7051 XTIFFClose (out);
7052 if (srs_name != NULL)
7053 free (srs_name);
7054 if (proj4text != NULL)
7055 free (proj4text);
7056 if (clientdata.buffer != NULL)
7057 free (clientdata.buffer);
7058 return 0;
7059 }
7060
7061 static int
palette_tiff_common(TIFF * out,const unsigned char * buffer,unsigned short width,unsigned short height,unsigned char * red,unsigned char * green,unsigned char * blue,int max_palette)7062 palette_tiff_common (TIFF * out, const unsigned char *buffer,
7063 unsigned short width, unsigned short height,
7064 unsigned char *red, unsigned char *green,
7065 unsigned char *blue, int max_palette)
7066 {
7067 /* common implementation of Palette TIFF export */
7068 tsize_t buf_size;
7069 void *tiff_buffer = NULL;
7070 int y;
7071 int x;
7072 int i;
7073 const unsigned char *p_in;
7074 unsigned char *p_out;
7075 uint16 r_plt[256];
7076 uint16 g_plt[256];
7077 uint16 b_plt[256];
7078
7079 /* preparing the TIFF palette */
7080 for (i = 0; i < 256; i++)
7081 {
7082 r_plt[i] = 0;
7083 g_plt[i] = 0;
7084 b_plt[i] = 0;
7085 }
7086 for (i = 0; i < max_palette; i++)
7087 {
7088 r_plt[i] = *(red + i) * 256;
7089 g_plt[i] = *(green + i) * 256;
7090 b_plt[i] = *(blue + i) * 256;
7091 }
7092
7093 /* setting up the TIFF headers */
7094 TIFFSetField (out, TIFFTAG_SUBFILETYPE, 0);
7095 TIFFSetField (out, TIFFTAG_IMAGEWIDTH, width);
7096 TIFFSetField (out, TIFFTAG_IMAGELENGTH, height);
7097 TIFFSetField (out, TIFFTAG_XRESOLUTION, 300.0);
7098 TIFFSetField (out, TIFFTAG_YRESOLUTION, 300.0);
7099 TIFFSetField (out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
7100 TIFFSetField (out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
7101 TIFFSetField (out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
7102 TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
7103 TIFFSetField (out, TIFFTAG_SAMPLESPERPIXEL, 1);
7104 TIFFSetField (out, TIFFTAG_BITSPERSAMPLE, 8);
7105 TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
7106 TIFFSetField (out, TIFFTAG_COLORMAP, r_plt, g_plt, b_plt);
7107 TIFFSetField (out, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
7108 TIFFSetField (out, TIFFTAG_ROWSPERSTRIP, 1);
7109
7110 /* allocating the TIFF write buffer */
7111 buf_size = TIFFScanlineSize (out);
7112 tiff_buffer = malloc (buf_size);
7113 if (tiff_buffer == NULL)
7114 goto error;
7115
7116 /* writing TIFF RGB scanlines */
7117 p_in = buffer;
7118
7119 for (y = 0; y < height; y++)
7120 {
7121 /* inserting pixels */
7122 p_out = tiff_buffer;
7123 for (x = 0; x < width; x++)
7124 {
7125 unsigned char r = *p_in++;
7126 unsigned char g = *p_in++;
7127 unsigned char b = *p_in++;
7128 unsigned char index = 0;
7129 for (i = 0; i < max_palette; i++)
7130 {
7131 if (*(red + i) == r && *(green + i) == g
7132 && *(blue + i) == b)
7133 {
7134 index = i;
7135 break;
7136 }
7137 }
7138 *p_out++ = index;
7139 }
7140 if (TIFFWriteScanline (out, tiff_buffer, y, 0) < 0)
7141 goto error;
7142 }
7143
7144 free (tiff_buffer);
7145 return 1;
7146 error:
7147 if (tiff_buffer != NULL)
7148 free (tiff_buffer);
7149 return 0;
7150 }
7151
7152 static int
output_palette_tiff(const unsigned char * buffer,unsigned short width,unsigned short height,unsigned char * red,unsigned char * green,unsigned char * blue,int max_palette,unsigned char ** blob,int * blob_size)7153 output_palette_tiff (const unsigned char *buffer,
7154 unsigned short width,
7155 unsigned short height, unsigned char *red,
7156 unsigned char *green, unsigned char *blue, int max_palette,
7157 unsigned char **blob, int *blob_size)
7158 {
7159 /* generating a PALETTE TIFF - actual work */
7160 struct memfile clientdata;
7161 TIFF *out = (TIFF *) 0;
7162
7163 /* suppressing TIFF warnings */
7164 TIFFSetWarningHandler (NULL);
7165
7166 /* writing into memory */
7167 clientdata.buffer = NULL;
7168 clientdata.malloc_block = 1024;
7169 clientdata.size = 0;
7170 clientdata.eof = 0;
7171 clientdata.current = 0;
7172 out = TIFFClientOpen ("tiff", "w", &clientdata, memory_readproc,
7173 memory_writeproc, memory_seekproc, closeproc,
7174 memory_sizeproc, mapproc, unmapproc);
7175 if (out == NULL)
7176 return 0;
7177
7178 if (!palette_tiff_common
7179 (out, buffer, width, height, red, green, blue, max_palette))
7180 goto error;
7181
7182 TIFFClose (out);
7183 *blob = clientdata.buffer;
7184 *blob_size = clientdata.eof;
7185 return 1;
7186
7187 error:
7188 TIFFClose (out);
7189 if (clientdata.buffer != NULL)
7190 free (clientdata.buffer);
7191 return 0;
7192 }
7193
7194 static int
output_palette_geotiff(const unsigned char * buffer,unsigned short width,unsigned short height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,unsigned char * red,unsigned char * green,unsigned char * blue,int max_palette,unsigned char ** blob,int * blob_size)7195 output_palette_geotiff (const unsigned char *buffer,
7196 unsigned short width,
7197 unsigned short height, sqlite3 * handle, double minx,
7198 double miny, double maxx, double maxy, int srid,
7199 unsigned char *red, unsigned char *green,
7200 unsigned char *blue, int max_palette,
7201 unsigned char **blob, int *blob_size)
7202 {
7203 /* generating a PALETTE GeoTIFF - actual work */
7204 struct memfile clientdata;
7205 double tiepoint[6];
7206 double pixsize[3];
7207 double hResolution = (maxx - minx) / (double) width;
7208 double vResolution = (maxy - miny) / (double) height;
7209 char *srs_name = NULL;
7210 char *proj4text = NULL;
7211 GTIF *gtif = (GTIF *) 0;
7212 TIFF *out = (TIFF *) 0;
7213
7214 /* suppressing TIFF warnings */
7215 TIFFSetWarningHandler (NULL);
7216
7217 /* writing into memory */
7218 clientdata.buffer = NULL;
7219 clientdata.malloc_block = 1024;
7220 clientdata.size = 0;
7221 clientdata.eof = 0;
7222 clientdata.current = 0;
7223
7224 out = XTIFFClientOpen ("tiff", "w", &clientdata, memory_readproc,
7225 memory_writeproc, memory_seekproc, closeproc,
7226 memory_sizeproc, mapproc, unmapproc);
7227 if (out == NULL)
7228 goto error;
7229 gtif = GTIFNew (out);
7230 if (gtif == NULL)
7231 goto error;
7232
7233 /* attempting to retrieve the CRS params */
7234 fetch_crs_params (handle, srid, &srs_name, &proj4text);
7235 if (srs_name == NULL || proj4text == NULL)
7236 goto error;
7237
7238 /* setting up the GeoTIFF Tags */
7239 pixsize[0] = hResolution;
7240 pixsize[1] = vResolution;
7241 pixsize[2] = 0.0;
7242 TIFFSetField (out, GTIFF_PIXELSCALE, 3, pixsize);
7243 tiepoint[0] = 0.0;
7244 tiepoint[1] = 0.0;
7245 tiepoint[2] = 0.0;
7246 tiepoint[3] = minx;
7247 tiepoint[4] = maxy;
7248 tiepoint[5] = 0.0;
7249 TIFFSetField (out, GTIFF_TIEPOINTS, 6, tiepoint);
7250 if (srs_name != NULL)
7251 TIFFSetField (out, GTIFF_ASCIIPARAMS, srs_name);
7252 if (proj4text != NULL)
7253 GTIFSetFromProj4 (gtif, proj4text);
7254 if (srs_name != NULL)
7255 GTIFKeySet (gtif, GTCitationGeoKey, TYPE_ASCII, 0, srs_name);
7256 if (is_projected_srs (proj4text))
7257 GTIFKeySet (gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, srid);
7258 GTIFWriteKeys (gtif);
7259
7260 if (!palette_tiff_common
7261 (out, buffer, width, height, red, green, blue, max_palette))
7262 goto error;
7263
7264 GTIFFree (gtif);
7265 XTIFFClose (out);
7266 *blob = clientdata.buffer;
7267 *blob_size = clientdata.eof;
7268 if (srs_name != NULL)
7269 free (srs_name);
7270 if (proj4text != NULL)
7271 free (proj4text);
7272 return 1;
7273
7274 error:
7275 if (gtif != (GTIF *) 0)
7276 GTIFFree (gtif);
7277 if (out != (TIFF *) 0)
7278 XTIFFClose (out);
7279 if (srs_name != NULL)
7280 free (srs_name);
7281 if (proj4text != NULL)
7282 free (proj4text);
7283 if (clientdata.buffer != NULL)
7284 free (clientdata.buffer);
7285 return 0;
7286 }
7287
7288 static int
test_palette_tiff(unsigned short width,unsigned short height,const unsigned char * rgb,unsigned char * red,unsigned char * green,unsigned char * blue,int * max_palette)7289 test_palette_tiff (unsigned short width, unsigned short height,
7290 const unsigned char *rgb, unsigned char *red,
7291 unsigned char *green, unsigned char *blue, int *max_palette)
7292 {
7293 /* testing for an eventual Palette */
7294 int next_palette = 0;
7295 int extra_palette = 0;
7296 int c;
7297 int y;
7298 int x;
7299 const unsigned char *p_in;
7300
7301 p_in = rgb;
7302 for (y = 0; y < height; y++)
7303 {
7304 /* inserting pixels */
7305 for (x = 0; x < width; x++)
7306 {
7307 unsigned char r = *p_in++;
7308 unsigned char g = *p_in++;
7309 unsigned char b = *p_in++;
7310 int match = 0;
7311 for (c = 0; c < next_palette; c++)
7312 {
7313 if (*(red + c) == r && *(green + c) == g
7314 && *(blue + c) == b)
7315 {
7316 /* color already defined into the palette */
7317 match = 1;
7318 break;
7319 }
7320 }
7321 if (!match)
7322 {
7323 /* attempting to insert a color into the palette */
7324 if (next_palette < 256)
7325 {
7326 *(red + next_palette) = r;
7327 *(green + next_palette) = g;
7328 *(blue + next_palette) = b;
7329 next_palette++;
7330 }
7331 else
7332 {
7333 extra_palette++;
7334 goto palette_invalid;
7335 }
7336 }
7337 }
7338 }
7339 palette_invalid:
7340 if (extra_palette)
7341 return 0;
7342 *max_palette = next_palette;
7343 return 1;
7344 }
7345
7346 RL2_DECLARE int
rl2_rgb_to_tiff(unsigned int width,unsigned int height,const unsigned char * rgb,unsigned char ** tiff,int * tiff_size)7347 rl2_rgb_to_tiff (unsigned int width, unsigned int height,
7348 const unsigned char *rgb, unsigned char **tiff, int *tiff_size)
7349 {
7350 /* creating a TIFF in-memory image from an RGB buffer */
7351 unsigned char red[256];
7352 unsigned char green[256];
7353 unsigned char blue[256];
7354 int max_palette = 0;
7355 if (rgb == NULL)
7356 return RL2_ERROR;
7357
7358 if (test_palette_tiff (width, height, rgb, red, green, blue, &max_palette))
7359 {
7360 if (!output_palette_tiff
7361 (rgb, width, height, red, green, blue, max_palette, tiff,
7362 tiff_size))
7363 return RL2_ERROR;
7364 }
7365 else
7366 {
7367 if (!output_rgb_tiff (rgb, width, height, tiff, tiff_size))
7368 return RL2_ERROR;
7369 }
7370 return RL2_OK;
7371 }
7372
7373 RL2_DECLARE int
rl2_rgb_to_geotiff(unsigned int width,unsigned int height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,const unsigned char * rgb,unsigned char ** tiff,int * tiff_size)7374 rl2_rgb_to_geotiff (unsigned int width, unsigned int height,
7375 sqlite3 * handle, double minx, double miny, double maxx,
7376 double maxy, int srid, const unsigned char *rgb,
7377 unsigned char **tiff, int *tiff_size)
7378 {
7379 /* creating a GeoTIFF in-memory image from an RGB buffer */
7380 unsigned char red[256];
7381 unsigned char green[256];
7382 unsigned char blue[256];
7383 int max_palette = 0;
7384 if (rgb == NULL)
7385 return RL2_ERROR;
7386
7387 if (test_palette_tiff (width, height, rgb, red, green, blue, &max_palette))
7388 {
7389 if (!output_palette_geotiff
7390 (rgb, width, height, handle, minx, miny, maxx, maxy, srid, red,
7391 green, blue, max_palette, tiff, tiff_size))
7392 return RL2_ERROR;
7393 }
7394 else
7395 {
7396 if (!output_rgb_geotiff
7397 (rgb, width, height, handle, minx, miny, maxx, maxy, srid, tiff,
7398 tiff_size))
7399 return RL2_ERROR;
7400 }
7401 return RL2_OK;
7402 }
7403
7404 static int
gray_tiff_common(TIFF * out,const unsigned char * buffer,unsigned short width,unsigned short height)7405 gray_tiff_common (TIFF * out, const unsigned char *buffer, unsigned short width,
7406 unsigned short height)
7407 {
7408 /* common implementation of Grayscale TIFF export */
7409 tsize_t buf_size;
7410 void *tiff_buffer = NULL;
7411 int y;
7412 int x;
7413 const unsigned char *p_in;
7414 unsigned char *p_out;
7415
7416 /* setting up the TIFF headers */
7417 TIFFSetField (out, TIFFTAG_SUBFILETYPE, 0);
7418 TIFFSetField (out, TIFFTAG_IMAGEWIDTH, width);
7419 TIFFSetField (out, TIFFTAG_IMAGELENGTH, height);
7420 TIFFSetField (out, TIFFTAG_XRESOLUTION, 300.0);
7421 TIFFSetField (out, TIFFTAG_YRESOLUTION, 300.0);
7422 TIFFSetField (out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
7423 TIFFSetField (out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
7424 TIFFSetField (out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
7425 TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
7426 TIFFSetField (out, TIFFTAG_SAMPLESPERPIXEL, 1);
7427 TIFFSetField (out, TIFFTAG_BITSPERSAMPLE, 8);
7428 TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
7429 TIFFSetField (out, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
7430 TIFFSetField (out, TIFFTAG_ROWSPERSTRIP, 1);
7431
7432 /* allocating the TIFF write buffer */
7433 buf_size = TIFFScanlineSize (out);
7434 tiff_buffer = malloc (buf_size);
7435 if (tiff_buffer == NULL)
7436 goto error;
7437
7438 /* writing TIFF RGB scanlines */
7439 p_in = buffer;
7440
7441 for (y = 0; y < height; y++)
7442 {
7443 /* inserting pixels */
7444 p_out = tiff_buffer;
7445 for (x = 0; x < width; x++)
7446 *p_out++ = *p_in++; /* gray */
7447 if (TIFFWriteScanline (out, tiff_buffer, y, 0) < 0)
7448 goto error;
7449 }
7450
7451 free (tiff_buffer);
7452 return 1;
7453 error:
7454 if (tiff_buffer != NULL)
7455 free (tiff_buffer);
7456 return 0;
7457 }
7458
7459 static int
output_gray_tiff(const unsigned char * buffer,unsigned short width,unsigned short height,unsigned char ** blob,int * blob_size)7460 output_gray_tiff (const unsigned char *buffer,
7461 unsigned short width,
7462 unsigned short height, unsigned char **blob, int *blob_size)
7463 {
7464 /* generating a Grayscale TIFF - actual work */
7465 struct memfile clientdata;
7466 TIFF *out = (TIFF *) 0;
7467
7468 /* suppressing TIFF warnings */
7469 TIFFSetWarningHandler (NULL);
7470
7471 /* writing into memory */
7472 clientdata.buffer = NULL;
7473 clientdata.malloc_block = 1024;
7474 clientdata.size = 0;
7475 clientdata.eof = 0;
7476 clientdata.current = 0;
7477 out = TIFFClientOpen ("tiff", "w", &clientdata, memory_readproc,
7478 memory_writeproc, memory_seekproc, closeproc,
7479 memory_sizeproc, mapproc, unmapproc);
7480 if (out == NULL)
7481 return 0;
7482
7483 if (!gray_tiff_common (out, buffer, width, height))
7484 goto error;
7485
7486 TIFFClose (out);
7487 *blob = clientdata.buffer;
7488 *blob_size = clientdata.eof;
7489 return 1;
7490
7491 error:
7492 TIFFClose (out);
7493 if (clientdata.buffer != NULL)
7494 free (clientdata.buffer);
7495 return 0;
7496 }
7497
7498 static int
output_gray_geotiff(const unsigned char * buffer,unsigned short width,unsigned short height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,unsigned char ** blob,int * blob_size)7499 output_gray_geotiff (const unsigned char *buffer,
7500 unsigned short width,
7501 unsigned short height, sqlite3 * handle, double minx,
7502 double miny, double maxx, double maxy, int srid,
7503 unsigned char **blob, int *blob_size)
7504 {
7505 /* generating a Grayscale GeoTIFF - actual work */
7506 struct memfile clientdata;
7507 double tiepoint[6];
7508 double pixsize[3];
7509 double hResolution = (maxx - minx) / (double) width;
7510 double vResolution = (maxy - miny) / (double) height;
7511 char *srs_name = NULL;
7512 char *proj4text = NULL;
7513 GTIF *gtif = (GTIF *) 0;
7514 TIFF *out = (TIFF *) 0;
7515
7516 /* suppressing TIFF warnings */
7517 TIFFSetWarningHandler (NULL);
7518
7519 /* writing into memory */
7520 clientdata.buffer = NULL;
7521 clientdata.malloc_block = 1024;
7522 clientdata.size = 0;
7523 clientdata.eof = 0;
7524 clientdata.current = 0;
7525
7526 out = XTIFFClientOpen ("tiff", "w", &clientdata, memory_readproc,
7527 memory_writeproc, memory_seekproc, closeproc,
7528 memory_sizeproc, mapproc, unmapproc);
7529 if (out == NULL)
7530 goto error;
7531 gtif = GTIFNew (out);
7532 if (gtif == NULL)
7533 goto error;
7534
7535 /* attempting to retrieve the CRS params */
7536 fetch_crs_params (handle, srid, &srs_name, &proj4text);
7537 if (srs_name == NULL || proj4text == NULL)
7538 goto error;
7539
7540 /* setting up the GeoTIFF Tags */
7541 pixsize[0] = hResolution;
7542 pixsize[1] = vResolution;
7543 pixsize[2] = 0.0;
7544 TIFFSetField (out, GTIFF_PIXELSCALE, 3, pixsize);
7545 tiepoint[0] = 0.0;
7546 tiepoint[1] = 0.0;
7547 tiepoint[2] = 0.0;
7548 tiepoint[3] = minx;
7549 tiepoint[4] = maxy;
7550 tiepoint[5] = 0.0;
7551 TIFFSetField (out, GTIFF_TIEPOINTS, 6, tiepoint);
7552 if (srs_name != NULL)
7553 TIFFSetField (out, GTIFF_ASCIIPARAMS, srs_name);
7554 if (proj4text != NULL)
7555 GTIFSetFromProj4 (gtif, proj4text);
7556 if (srs_name != NULL)
7557 GTIFKeySet (gtif, GTCitationGeoKey, TYPE_ASCII, 0, srs_name);
7558 if (is_projected_srs (proj4text))
7559 GTIFKeySet (gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, srid);
7560 GTIFWriteKeys (gtif);
7561
7562 if (!gray_tiff_common (out, buffer, width, height))
7563 goto error;
7564
7565 GTIFFree (gtif);
7566 XTIFFClose (out);
7567 *blob = clientdata.buffer;
7568 *blob_size = clientdata.eof;
7569 if (srs_name != NULL)
7570 free (srs_name);
7571 if (proj4text != NULL)
7572 free (proj4text);
7573 return 1;
7574
7575 error:
7576 if (gtif != (GTIF *) 0)
7577 GTIFFree (gtif);
7578 if (out != (TIFF *) 0)
7579 XTIFFClose (out);
7580 if (srs_name != NULL)
7581 free (srs_name);
7582 if (proj4text != NULL)
7583 free (proj4text);
7584 if (clientdata.buffer != NULL)
7585 free (clientdata.buffer);
7586 return 0;
7587 }
7588
7589 RL2_DECLARE int
rl2_gray_to_tiff(unsigned int width,unsigned int height,const unsigned char * gray,unsigned char ** tiff,int * tiff_size)7590 rl2_gray_to_tiff (unsigned int width, unsigned int height,
7591 const unsigned char *gray, unsigned char **tiff,
7592 int *tiff_size)
7593 {
7594 /* creating a TIFF in-memory image from a Grayscale buffer */
7595 if (gray == NULL)
7596 return RL2_ERROR;
7597
7598 if (!output_gray_tiff (gray, width, height, tiff, tiff_size))
7599 return RL2_ERROR;
7600 return RL2_OK;
7601 }
7602
7603 RL2_DECLARE int
rl2_gray_to_geotiff(unsigned int width,unsigned int height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,const unsigned char * gray,unsigned char ** tiff,int * tiff_size)7604 rl2_gray_to_geotiff (unsigned int width, unsigned int height,
7605 sqlite3 * handle, double minx, double miny, double maxx,
7606 double maxy, int srid, const unsigned char *gray,
7607 unsigned char **tiff, int *tiff_size)
7608 {
7609 /* creating a GeoTIFF in-memory image from a Grayscale buffer */
7610 if (gray == NULL)
7611 return RL2_ERROR;
7612
7613 if (!output_gray_geotiff
7614 (gray, width, height, handle, minx, miny, maxx, maxy, srid, tiff,
7615 tiff_size))
7616 return RL2_ERROR;
7617 return RL2_OK;
7618 }
7619
7620 RL2_DECLARE rl2RasterPtr
rl2_raster_from_tiff(const unsigned char * blob,int blob_size)7621 rl2_raster_from_tiff (const unsigned char *blob, int blob_size)
7622 {
7623 /* attempting to create a raster from a TIFF image */
7624 rl2RasterPtr rst = NULL;
7625 struct memfile clientdata;
7626 uint32 width = 0;
7627 uint32 height = 0;
7628 TIFF *in = (TIFF *) 0;
7629 unsigned int x;
7630 unsigned int y;
7631 unsigned int row;
7632 uint32 *rgba;
7633 unsigned char *rgb;
7634 unsigned char *mask;
7635 int rgb_size;
7636 int mask_size;
7637 uint32 *p_in;
7638 unsigned char *p_rgb;
7639 unsigned char *p_mask;
7640 int valid_mask = 0;
7641
7642 /* suppressing TIFF warnings */
7643 TIFFSetWarningHandler (NULL);
7644
7645 /* reading from memory */
7646 clientdata.buffer = (unsigned char *) blob;
7647 clientdata.malloc_block = 1024;
7648 clientdata.size = blob_size;
7649 clientdata.eof = blob_size;
7650 clientdata.current = 0;
7651 in = TIFFClientOpen ("tiff", "r", &clientdata, memory_readproc,
7652 memory_writeproc, memory_seekproc, closeproc,
7653 memory_sizeproc, mapproc, unmapproc);
7654 if (in == NULL)
7655 return NULL;
7656
7657 /* retrieving the TIFF dimensions */
7658 TIFFGetField (in, TIFFTAG_IMAGELENGTH, &height);
7659 TIFFGetField (in, TIFFTAG_IMAGEWIDTH, &width);
7660
7661 /* allocating the RGBA buffer */
7662 rgba = malloc (sizeof (uint32) * width * height);
7663 if (rgba == NULL)
7664 goto error;
7665
7666 /* attempting to decode the TIFF */
7667 if (!TIFFReadRGBAImage (in, width, height, rgba, 1))
7668 goto error;
7669 TIFFClose (in);
7670
7671 /* rearranging the RGBA buffer */
7672 rgb_size = width * height * 3;
7673 mask_size = width * height;
7674 rgb = malloc (rgb_size);
7675 mask = malloc (mask_size);
7676 if (rgb == NULL || mask == NULL)
7677 goto error;
7678 p_in = rgba;
7679 row = height - 1;
7680 for (y = 0; y < height; y++)
7681 {
7682 /* the TIFF RGBA buffer is bottom-up !!! */
7683 p_rgb = rgb + (row * width * 3);
7684 p_mask = mask + (row * width);
7685 for (x = 0; x < width; x++)
7686 {
7687 /* copying pixels */
7688 *p_rgb++ = TIFFGetR (*p_in);
7689 *p_rgb++ = TIFFGetG (*p_in);
7690 *p_rgb++ = TIFFGetB (*p_in);
7691 if (TIFFGetA (*p_in) < 128)
7692 {
7693 *p_mask++ = 0;
7694 valid_mask = 1;
7695 }
7696 else
7697 *p_mask++ = 1;
7698 p_in++;
7699 }
7700 row--;
7701 }
7702 if (!valid_mask)
7703 {
7704 free (mask);
7705 mask = NULL;
7706 mask_size = 0;
7707 }
7708 free (rgba);
7709 rgba = NULL;
7710
7711 /* creating the raster */
7712 rst =
7713 rl2_create_raster (width, height, RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3,
7714 rgb, rgb_size, NULL, mask, mask_size, NULL);
7715 if (rst == NULL)
7716 goto error;
7717 return rst;
7718
7719 error:
7720 if (in != (TIFF *) 0)
7721 TIFFClose (in);
7722 if (rgba != NULL)
7723 free (rgba);
7724 if (rgb != NULL)
7725 free (rgb);
7726 if (mask != NULL)
7727 free (mask);
7728 return NULL;
7729 }
7730