1 /*
2
3 rasterlite2 -- main public functions
4
5 version 0.1, 2013 March 29
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
49 #include "config.h"
50
51 #ifdef LOADABLE_EXTENSION
52 #include "rasterlite2/sqlite.h"
53 #endif
54
55 #include "rasterlite2/rasterlite2.h"
56 #include "rasterlite2_private.h"
57
58 static int
is_valid_sample_type(unsigned char sample_type)59 is_valid_sample_type (unsigned char sample_type)
60 {
61 /* checking a sample-type for validity */
62 switch (sample_type)
63 {
64 case RL2_SAMPLE_1_BIT:
65 case RL2_SAMPLE_2_BIT:
66 case RL2_SAMPLE_4_BIT:
67 case RL2_SAMPLE_INT8:
68 case RL2_SAMPLE_UINT8:
69 case RL2_SAMPLE_INT16:
70 case RL2_SAMPLE_UINT16:
71 case RL2_SAMPLE_INT32:
72 case RL2_SAMPLE_UINT32:
73 case RL2_SAMPLE_FLOAT:
74 case RL2_SAMPLE_DOUBLE:
75 return 1;
76 };
77 return 0;
78 }
79
80 static int
is_valid_pixel_type(unsigned char pixel_type)81 is_valid_pixel_type (unsigned char pixel_type)
82 {
83 /* checking a pixel-type for validity */
84 switch (pixel_type)
85 {
86 case RL2_PIXEL_MONOCHROME:
87 case RL2_PIXEL_PALETTE:
88 case RL2_PIXEL_GRAYSCALE:
89 case RL2_PIXEL_RGB:
90 case RL2_PIXEL_MULTIBAND:
91 case RL2_PIXEL_DATAGRID:
92 return 1;
93 };
94 return 0;
95 }
96
97 static int
is_valid_compression(unsigned char compression)98 is_valid_compression (unsigned char compression)
99 {
100 /* checking a compression-type for validity */
101 switch (compression)
102 {
103 case RL2_COMPRESSION_NONE:
104 case RL2_COMPRESSION_DEFLATE:
105 case RL2_COMPRESSION_LZMA:
106 case RL2_COMPRESSION_GIF:
107 case RL2_COMPRESSION_PNG:
108 case RL2_COMPRESSION_JPEG:
109 case RL2_COMPRESSION_LOSSY_WEBP:
110 case RL2_COMPRESSION_LOSSLESS_WEBP:
111 case RL2_COMPRESSION_CCITTFAX4:
112 return 1;
113 };
114 return 0;
115 }
116
117 static int
check_coverage_self_consistency(unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples,unsigned char compression)118 check_coverage_self_consistency (unsigned char sample_type,
119 unsigned char pixel_type,
120 unsigned char num_samples,
121 unsigned char compression)
122 {
123 /* checking overall self-consistency for coverage params */
124 switch (pixel_type)
125 {
126 case RL2_PIXEL_MONOCHROME:
127 if (sample_type != RL2_SAMPLE_1_BIT || num_samples != 1)
128 return 0;
129 switch (compression)
130 {
131 case RL2_COMPRESSION_NONE:
132 case RL2_COMPRESSION_PNG:
133 case RL2_COMPRESSION_CCITTFAX4:
134 break;
135 default:
136 return 0;
137 };
138 break;
139 case RL2_PIXEL_PALETTE:
140 switch (sample_type)
141 {
142 case RL2_SAMPLE_1_BIT:
143 case RL2_SAMPLE_2_BIT:
144 case RL2_SAMPLE_4_BIT:
145 case RL2_SAMPLE_UINT8:
146 break;
147 default:
148 return 0;
149 };
150 if (num_samples != 1)
151 return 0;
152 switch (compression)
153 {
154 case RL2_COMPRESSION_NONE:
155 case RL2_COMPRESSION_GIF:
156 case RL2_COMPRESSION_PNG:
157 break;
158 default:
159 return 0;
160 };
161 break;
162 case RL2_PIXEL_GRAYSCALE:
163 switch (sample_type)
164 {
165 case RL2_SAMPLE_2_BIT:
166 case RL2_SAMPLE_4_BIT:
167 case RL2_SAMPLE_UINT8:
168 break;
169 default:
170 return 0;
171 };
172 if (num_samples != 1)
173 return 0;
174 switch (compression)
175 {
176 case RL2_COMPRESSION_NONE:
177 case RL2_COMPRESSION_DEFLATE:
178 case RL2_COMPRESSION_LZMA:
179 case RL2_COMPRESSION_GIF:
180 case RL2_COMPRESSION_PNG:
181 case RL2_COMPRESSION_JPEG:
182 case RL2_COMPRESSION_LOSSY_WEBP:
183 case RL2_COMPRESSION_LOSSLESS_WEBP:
184 break;
185 default:
186 return 0;
187 };
188 break;
189 case RL2_PIXEL_RGB:
190 switch (sample_type)
191 {
192 case RL2_SAMPLE_UINT8:
193 case RL2_SAMPLE_UINT16:
194 break;
195 default:
196 return 0;
197 };
198 if (num_samples != 3)
199 return 0;
200 if (sample_type == RL2_SAMPLE_UINT16)
201 {
202 switch (compression)
203 {
204 case RL2_COMPRESSION_NONE:
205 case RL2_COMPRESSION_DEFLATE:
206 case RL2_COMPRESSION_LZMA:
207 break;
208 default:
209 return 0;
210 };
211 }
212 else
213 {
214 switch (compression)
215 {
216 case RL2_COMPRESSION_NONE:
217 case RL2_COMPRESSION_DEFLATE:
218 case RL2_COMPRESSION_LZMA:
219 case RL2_COMPRESSION_PNG:
220 case RL2_COMPRESSION_JPEG:
221 case RL2_COMPRESSION_LOSSY_WEBP:
222 case RL2_COMPRESSION_LOSSLESS_WEBP:
223 break;
224 default:
225 return 0;
226 };
227 }
228 break;
229 case RL2_PIXEL_MULTIBAND:
230 switch (sample_type)
231 {
232 case RL2_SAMPLE_UINT8:
233 case RL2_SAMPLE_UINT16:
234 break;
235 default:
236 return 0;
237 };
238 if (num_samples < 2)
239 return 0;
240 switch (compression)
241 {
242 case RL2_COMPRESSION_NONE:
243 case RL2_COMPRESSION_DEFLATE:
244 case RL2_COMPRESSION_LZMA:
245 break;
246 default:
247 return 0;
248 };
249 break;
250 case RL2_PIXEL_DATAGRID:
251 switch (sample_type)
252 {
253 case RL2_SAMPLE_INT8:
254 case RL2_SAMPLE_UINT8:
255 case RL2_SAMPLE_INT16:
256 case RL2_SAMPLE_UINT16:
257 case RL2_SAMPLE_INT32:
258 case RL2_SAMPLE_UINT32:
259 case RL2_SAMPLE_FLOAT:
260 case RL2_SAMPLE_DOUBLE:
261 break;
262 default:
263 return 0;
264 };
265 if (num_samples != 1)
266 return 0;
267 switch (compression)
268 {
269 case RL2_COMPRESSION_NONE:
270 case RL2_COMPRESSION_DEFLATE:
271 case RL2_COMPRESSION_LZMA:
272 break;
273 default:
274 return 0;
275 };
276 break;
277 };
278 return 1;
279 }
280
281 static int
check_raster_self_consistency(unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples)282 check_raster_self_consistency (unsigned char sample_type,
283 unsigned char pixel_type,
284 unsigned char num_samples)
285 {
286 /* checking overall self-consistency for raster params */
287 switch (pixel_type)
288 {
289 case RL2_PIXEL_MONOCHROME:
290 if (sample_type != RL2_SAMPLE_1_BIT || num_samples != 1)
291 return 0;
292 break;
293 case RL2_PIXEL_PALETTE:
294 switch (sample_type)
295 {
296 case RL2_SAMPLE_1_BIT:
297 case RL2_SAMPLE_2_BIT:
298 case RL2_SAMPLE_4_BIT:
299 case RL2_SAMPLE_UINT8:
300 break;
301 default:
302 return 0;
303 };
304 if (num_samples != 1)
305 return 0;
306 break;
307 case RL2_PIXEL_GRAYSCALE:
308 switch (sample_type)
309 {
310 case RL2_SAMPLE_2_BIT:
311 case RL2_SAMPLE_4_BIT:
312 case RL2_SAMPLE_UINT8:
313 case RL2_SAMPLE_UINT16:
314 break;
315 default:
316 return 0;
317 };
318 if (num_samples != 1)
319 return 0;
320 break;
321 case RL2_PIXEL_RGB:
322 switch (sample_type)
323 {
324 case RL2_SAMPLE_UINT8:
325 case RL2_SAMPLE_UINT16:
326 break;
327 default:
328 return 0;
329 };
330 if (num_samples != 3)
331 return 0;
332 break;
333 case RL2_PIXEL_MULTIBAND:
334 switch (sample_type)
335 {
336 case RL2_SAMPLE_UINT8:
337 case RL2_SAMPLE_UINT16:
338 break;
339 default:
340 return 0;
341 };
342 if (num_samples < 2)
343 return 0;
344 break;
345 case RL2_PIXEL_DATAGRID:
346 switch (sample_type)
347 {
348 case RL2_SAMPLE_INT8:
349 case RL2_SAMPLE_UINT8:
350 case RL2_SAMPLE_INT16:
351 case RL2_SAMPLE_UINT16:
352 case RL2_SAMPLE_INT32:
353 case RL2_SAMPLE_UINT32:
354 case RL2_SAMPLE_FLOAT:
355 case RL2_SAMPLE_DOUBLE:
356 break;
357 default:
358 return 0;
359 };
360 if (num_samples != 1)
361 return 0;
362 break;
363 };
364 return 1;
365 }
366
367 RL2_DECLARE void
rl2_free(void * ptr)368 rl2_free (void *ptr)
369 {
370 /* memory cleanup - generic free */
371 if (ptr != NULL)
372 free (ptr);
373 }
374
375 static int
check_coverage_no_data(rl2PrivPixelPtr pxl_no_data,unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples)376 check_coverage_no_data (rl2PrivPixelPtr pxl_no_data, unsigned char sample_type,
377 unsigned char pixel_type, unsigned char num_samples)
378 {
379 /* checking if the NoData pixel is consistent with the Coverage */
380 if (pxl_no_data == NULL)
381 return 1;
382 if (pxl_no_data->sampleType != sample_type)
383 return 0;
384 if (pxl_no_data->pixelType != pixel_type)
385 return 0;
386 if (pxl_no_data->nBands != num_samples)
387 return 0;
388 return 1;
389 }
390
391 RL2_DECLARE rl2CoveragePtr
rl2_create_coverage(const char * name,unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples,unsigned char compression,int quality,unsigned int tile_width,unsigned int tile_height,rl2PixelPtr no_data)392 rl2_create_coverage (const char *name, unsigned char sample_type,
393 unsigned char pixel_type, unsigned char num_samples,
394 unsigned char compression, int quality,
395 unsigned int tile_width, unsigned int tile_height,
396 rl2PixelPtr no_data)
397 {
398 /* allocating and initializing a Coverage object */
399 int len;
400 rl2PrivPixelPtr pxl_no_data = (rl2PrivPixelPtr) no_data;
401 rl2PrivCoveragePtr cvg = NULL;
402 if (name == NULL)
403 return NULL;
404 if (!is_valid_sample_type (sample_type))
405 return NULL;
406 if (!is_valid_pixel_type (pixel_type))
407 return NULL;
408 if (!is_valid_compression (compression))
409 return NULL;
410 if (!check_coverage_self_consistency
411 (sample_type, pixel_type, num_samples, compression))
412 return NULL;
413 if (tile_width < 256 || tile_width > 1024)
414 return NULL;
415 if (tile_height < 256 || tile_height > 1024)
416 return NULL;
417 if ((tile_width % 16) != 0)
418 return NULL;
419 if ((tile_height % 16) != 0)
420 return NULL;
421 if (!check_coverage_no_data
422 (pxl_no_data, sample_type, pixel_type, num_samples))
423 return NULL;
424
425 cvg = malloc (sizeof (rl2PrivCoverage));
426 if (cvg == NULL)
427 return NULL;
428 len = strlen (name);
429 cvg->coverageName = malloc (len + 1);
430 strcpy (cvg->coverageName, name);
431 cvg->sampleType = sample_type;
432 cvg->pixelType = pixel_type;
433 cvg->nBands = num_samples;
434 cvg->Compression = compression;
435 if (quality < 0)
436 cvg->Quality = 0;
437 else if (quality > 100)
438 cvg->Quality = 100;
439 else
440 cvg->Quality = quality;
441 cvg->tileWidth = tile_width;
442 cvg->tileHeight = tile_height;
443 cvg->Srid = RL2_GEOREFERENCING_NONE;
444 cvg->hResolution = 1.0;
445 cvg->vResolution = 1.0;
446 cvg->noData = pxl_no_data;
447 return (rl2CoveragePtr) cvg;
448 }
449
450 RL2_DECLARE void
rl2_destroy_coverage(rl2CoveragePtr ptr)451 rl2_destroy_coverage (rl2CoveragePtr ptr)
452 {
453 /* memory cleanup - destroying a Coverage object */
454 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
455 if (cvg == NULL)
456 return;
457 if (cvg->coverageName != NULL)
458 free (cvg->coverageName);
459 if (cvg->noData != NULL)
460 rl2_destroy_pixel ((rl2PixelPtr) (cvg->noData));
461 free (cvg);
462 }
463
464 RL2_DECLARE int
rl2_coverage_georeference(rl2CoveragePtr ptr,int srid,double horz_res,double vert_res)465 rl2_coverage_georeference (rl2CoveragePtr ptr, int srid, double horz_res,
466 double vert_res)
467 {
468 /* setting the Coverage's georeferencing infos */
469 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
470 if (cvg == NULL)
471 return RL2_ERROR;
472 cvg->Srid = srid;
473 cvg->hResolution = horz_res;
474 cvg->vResolution = vert_res;
475 return RL2_OK;
476 }
477
478 RL2_DECLARE const char *
rl2_get_coverage_name(rl2CoveragePtr ptr)479 rl2_get_coverage_name (rl2CoveragePtr ptr)
480 {
481 /* return the Coverage name */
482 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
483 if (cvg == NULL)
484 return NULL;
485 return cvg->coverageName;
486 }
487
488 RL2_DECLARE int
rl2_get_coverage_type(rl2CoveragePtr ptr,unsigned char * sample_type,unsigned char * pixel_type,unsigned char * num_bands)489 rl2_get_coverage_type (rl2CoveragePtr ptr, unsigned char *sample_type,
490 unsigned char *pixel_type, unsigned char *num_bands)
491 {
492 /* return the Coverage type */
493 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
494 if (cvg == NULL)
495 return RL2_ERROR;
496 *sample_type = cvg->sampleType;
497 *pixel_type = cvg->pixelType;
498 *num_bands = cvg->nBands;
499 return RL2_OK;
500 }
501
502 RL2_DECLARE int
rl2_get_coverage_compression(rl2CoveragePtr ptr,unsigned char * compression,int * quality)503 rl2_get_coverage_compression (rl2CoveragePtr ptr, unsigned char *compression,
504 int *quality)
505 {
506 /* return the Coverage compression */
507 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
508 if (cvg == NULL)
509 return RL2_ERROR;
510 *compression = cvg->Compression;
511 *quality = cvg->Quality;
512 return RL2_OK;
513 }
514
515 RL2_DECLARE int
rl2_is_coverage_uncompressed(rl2CoveragePtr ptr,int * is_uncompressed)516 rl2_is_coverage_uncompressed (rl2CoveragePtr ptr, int *is_uncompressed)
517 {
518 /* tests if Coverage is compressed */
519 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
520 if (cvg == NULL)
521 return RL2_ERROR;
522 if (cvg->Compression == RL2_COMPRESSION_NONE)
523 *is_uncompressed = RL2_TRUE;
524 else
525 *is_uncompressed = RL2_FALSE;
526 return RL2_OK;
527 }
528
529 RL2_DECLARE int
rl2_is_coverage_compression_lossless(rl2CoveragePtr ptr,int * is_lossless)530 rl2_is_coverage_compression_lossless (rl2CoveragePtr ptr, int *is_lossless)
531 {
532 /* tests if Coverage is lossless compressed */
533 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
534 if (cvg == NULL)
535 return RL2_ERROR;
536 switch (cvg->Compression)
537 {
538 case RL2_COMPRESSION_DEFLATE:
539 case RL2_COMPRESSION_LZMA:
540 case RL2_COMPRESSION_GIF:
541 case RL2_COMPRESSION_PNG:
542 *is_lossless = RL2_TRUE;
543 break;
544 default:
545 *is_lossless = RL2_FALSE;
546 break;
547 };
548 return RL2_OK;
549 }
550
551 RL2_DECLARE int
rl2_is_coverage_compression_lossy(rl2CoveragePtr ptr,int * is_lossy)552 rl2_is_coverage_compression_lossy (rl2CoveragePtr ptr, int *is_lossy)
553 {
554 /* tests if Coverage is lossy compressed */
555 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
556 if (cvg == NULL)
557 return RL2_ERROR;
558 switch (cvg->Compression)
559 {
560 case RL2_COMPRESSION_JPEG:
561 case RL2_COMPRESSION_LOSSY_WEBP:
562 *is_lossy = RL2_TRUE;
563 break;
564 default:
565 *is_lossy = RL2_FALSE;
566 break;
567 };
568 return RL2_OK;
569 }
570
571 RL2_DECLARE int
rl2_get_coverage_tile_size(rl2CoveragePtr ptr,unsigned int * tile_width,unsigned int * tile_height)572 rl2_get_coverage_tile_size (rl2CoveragePtr ptr, unsigned int *tile_width,
573 unsigned int *tile_height)
574 {
575 /* return the Coverage tile width */
576 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
577 if (cvg == NULL)
578 return RL2_ERROR;
579 *tile_width = cvg->tileWidth;
580 *tile_height = cvg->tileHeight;
581 return RL2_OK;
582 }
583
584 RL2_DECLARE rl2PixelPtr
rl2_get_coverage_no_data(rl2CoveragePtr ptr)585 rl2_get_coverage_no_data (rl2CoveragePtr ptr)
586 {
587 /* return the Coverage NoData pixel (if any) */
588 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
589 if (cvg == NULL)
590 return NULL;
591 return (rl2PixelPtr) (cvg->noData);
592 }
593
594 RL2_DECLARE rl2PixelPtr
rl2_create_coverage_pixel(rl2CoveragePtr ptr)595 rl2_create_coverage_pixel (rl2CoveragePtr ptr)
596 {
597 /* creating a Pixel matching the given Coverage */
598 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
599 if (cvg == NULL)
600 return NULL;
601 return rl2_create_pixel (cvg->sampleType, cvg->pixelType, cvg->nBands);
602 }
603
604 RL2_DECLARE int
rl2_get_coverage_srid(rl2CoveragePtr ptr,int * srid)605 rl2_get_coverage_srid (rl2CoveragePtr ptr, int *srid)
606 {
607 /* return the Coverage SRID */
608 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
609 if (cvg == NULL)
610 return RL2_ERROR;
611 *srid = cvg->Srid;
612 return RL2_OK;
613 }
614
615 RL2_DECLARE int
rl2_get_coverage_resolution(rl2CoveragePtr ptr,double * hResolution,double * vResolution)616 rl2_get_coverage_resolution (rl2CoveragePtr ptr, double *hResolution,
617 double *vResolution)
618 {
619 /* return the Coverage SRID */
620 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
621 if (cvg == NULL)
622 return RL2_ERROR;
623 *hResolution = cvg->hResolution;
624 *vResolution = cvg->vResolution;
625 return RL2_OK;
626 }
627
628 RL2_DECLARE rl2SectionPtr
rl2_create_section(const char * name,unsigned char compression,unsigned int tile_width,unsigned int tile_height,rl2RasterPtr rst)629 rl2_create_section (const char *name, unsigned char compression,
630 unsigned int tile_width, unsigned int tile_height,
631 rl2RasterPtr rst)
632 {
633 /* allocating and initializing a Section object */
634 int len;
635 rl2PrivRasterPtr raster = (rl2PrivRasterPtr) rst;
636 rl2PrivSectionPtr scn = NULL;
637 if (name == NULL)
638 return NULL;
639 if (raster == NULL)
640 return NULL;
641 if (!check_coverage_self_consistency
642 (raster->sampleType, raster->pixelType, raster->nBands, compression))
643 return NULL;
644 if (tile_width == RL2_TILESIZE_UNDEFINED
645 && tile_height == RL2_TILESIZE_UNDEFINED)
646 ;
647 else
648 {
649 if (tile_width < 256 || tile_width > 1024)
650 return NULL;
651 if (tile_height < 256 || tile_height > 1024)
652 return NULL;
653 if ((tile_width % 16) != 0)
654 return NULL;
655 if ((tile_height % 16) != 0)
656 return NULL;
657 }
658
659 scn = malloc (sizeof (rl2PrivSection));
660 if (scn == NULL)
661 return NULL;
662 len = strlen (name);
663 scn->sectionName = malloc (len + 1);
664 strcpy (scn->sectionName, name);
665 scn->Compression = compression;
666 scn->tileWidth = tile_width;
667 scn->tileHeight = tile_height;
668 scn->Raster = raster;
669 return (rl2SectionPtr) scn;
670 }
671
672 RL2_DECLARE void
rl2_destroy_section(rl2SectionPtr ptr)673 rl2_destroy_section (rl2SectionPtr ptr)
674 {
675 /* memory cleanup - destroying a Section object */
676 rl2PrivSectionPtr scn = (rl2PrivSectionPtr) ptr;
677 if (scn == NULL)
678 return;
679 if (scn->sectionName != NULL)
680 free (scn->sectionName);
681 if (scn->Raster != NULL)
682 rl2_destroy_raster ((rl2RasterPtr) (scn->Raster));
683 free (scn);
684 }
685
686 RL2_DECLARE const char *
rl2_get_section_name(rl2SectionPtr ptr)687 rl2_get_section_name (rl2SectionPtr ptr)
688 {
689 /* return the Section name */
690 rl2PrivSectionPtr scn = (rl2PrivSectionPtr) ptr;
691 if (scn == NULL)
692 return NULL;
693 return scn->sectionName;
694 }
695
696 RL2_DECLARE int
rl2_get_section_compression(rl2SectionPtr ptr,unsigned char * compression)697 rl2_get_section_compression (rl2SectionPtr ptr, unsigned char *compression)
698 {
699 /* return the Section compression */
700 rl2PrivSectionPtr scn = (rl2PrivSectionPtr) ptr;
701 if (scn == NULL)
702 return RL2_ERROR;
703 *compression = scn->Compression;
704 return RL2_OK;
705 }
706
707 RL2_DECLARE int
rl2_is_section_uncompressed(rl2SectionPtr ptr,int * is_uncompressed)708 rl2_is_section_uncompressed (rl2SectionPtr ptr, int *is_uncompressed)
709 {
710 /* tests if Section is compressed */
711 rl2PrivSectionPtr scn = (rl2PrivSectionPtr) ptr;
712 if (scn == NULL)
713 return RL2_ERROR;
714 if (scn->Compression == RL2_COMPRESSION_NONE)
715 *is_uncompressed = RL2_TRUE;
716 else
717 *is_uncompressed = RL2_FALSE;
718 return RL2_OK;
719 }
720
721 RL2_DECLARE int
rl2_is_section_compression_lossless(rl2SectionPtr ptr,int * is_lossless)722 rl2_is_section_compression_lossless (rl2SectionPtr ptr, int *is_lossless)
723 {
724 /* tests if Section is lossless compressed */
725 rl2PrivSectionPtr scn = (rl2PrivSectionPtr) ptr;
726 if (scn == NULL)
727 return RL2_ERROR;
728 switch (scn->Compression)
729 {
730 case RL2_COMPRESSION_DEFLATE:
731 case RL2_COMPRESSION_LZMA:
732 case RL2_COMPRESSION_GIF:
733 case RL2_COMPRESSION_PNG:
734 case RL2_COMPRESSION_LOSSLESS_WEBP:
735 *is_lossless = RL2_TRUE;
736 break;
737 default:
738 *is_lossless = RL2_FALSE;
739 break;
740 };
741 return RL2_OK;
742 }
743
744 RL2_DECLARE int
rl2_is_section_compression_lossy(rl2SectionPtr ptr,int * is_lossy)745 rl2_is_section_compression_lossy (rl2SectionPtr ptr, int *is_lossy)
746 {
747 /* tests if Section is lossy compressed */
748 rl2PrivSectionPtr scn = (rl2PrivSectionPtr) ptr;
749 if (scn == NULL)
750 return RL2_ERROR;
751 switch (scn->Compression)
752 {
753 case RL2_COMPRESSION_JPEG:
754 case RL2_COMPRESSION_LOSSY_WEBP:
755 *is_lossy = RL2_TRUE;
756 break;
757 default:
758 *is_lossy = RL2_FALSE;
759 break;
760 };
761 return RL2_OK;
762 }
763
764 RL2_DECLARE int
rl2_get_section_tile_size(rl2SectionPtr ptr,unsigned int * tile_width,unsigned int * tile_height)765 rl2_get_section_tile_size (rl2SectionPtr ptr, unsigned int *tile_width,
766 unsigned int *tile_height)
767 {
768 /* return the Section tile width */
769 rl2PrivSectionPtr scn = (rl2PrivSectionPtr) ptr;
770 if (scn == NULL)
771 return RL2_ERROR;
772 *tile_width = scn->tileWidth;
773 *tile_height = scn->tileHeight;
774 return RL2_OK;
775 }
776
777 RL2_DECLARE rl2RasterPtr
rl2_get_section_raster(rl2SectionPtr ptr)778 rl2_get_section_raster (rl2SectionPtr ptr)
779 {
780 /* return the Section Raster */
781 rl2PrivSectionPtr scn = (rl2PrivSectionPtr) ptr;
782 if (scn == NULL)
783 return NULL;
784 return (rl2RasterPtr) (scn->Raster);
785 }
786
787 int
compute_raster_buffer_size(unsigned short width,unsigned short height,unsigned char sample_type,unsigned char num_samples)788 compute_raster_buffer_size (unsigned short width, unsigned short height,
789 unsigned char sample_type,
790 unsigned char num_samples)
791 {
792 /* determining the pixel buffer size */
793 int pixel_size = 1;
794 switch (sample_type)
795 {
796 case RL2_SAMPLE_INT16:
797 case RL2_SAMPLE_UINT16:
798 pixel_size = 2;
799 break;
800 case RL2_SAMPLE_INT32:
801 case RL2_SAMPLE_UINT32:
802 case RL2_SAMPLE_FLOAT:
803 pixel_size = 4;
804 break;
805 case RL2_SAMPLE_DOUBLE:
806 pixel_size = 8;
807 break;
808 };
809 return width * height * pixel_size * num_samples;
810 }
811
812 static int
check_raster_no_data(rl2PrivPixelPtr pxl_no_data,unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples)813 check_raster_no_data (rl2PrivPixelPtr pxl_no_data, unsigned char sample_type,
814 unsigned char pixel_type, unsigned char num_samples)
815 {
816 /* checking if the NoData pixel is consistent with the Raster */
817 if (pxl_no_data == NULL)
818 return 1;
819 if (pxl_no_data->sampleType != sample_type)
820 return 0;
821 if (pxl_no_data->pixelType != pixel_type)
822 return 0;
823 if (pxl_no_data->nBands != num_samples)
824 return 0;
825 return 1;
826 }
827
828 RL2_DECLARE rl2RasterPtr
rl2_create_raster(unsigned int width,unsigned int height,unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples,unsigned char * bufpix,int bufpix_size,rl2PalettePtr palette,unsigned char * mask,int mask_size,rl2PixelPtr no_data)829 rl2_create_raster (unsigned int width, unsigned int height,
830 unsigned char sample_type, unsigned char pixel_type,
831 unsigned char num_samples, unsigned char *bufpix,
832 int bufpix_size, rl2PalettePtr palette, unsigned char *mask,
833 int mask_size, rl2PixelPtr no_data)
834 {
835 /* allocating and initializing a Raster object */
836 rl2PrivPixelPtr pxl_no_data = (rl2PrivPixelPtr) no_data;
837 unsigned char *p;
838 unsigned int row;
839 unsigned int col;
840 int raster_size;
841 rl2PrivRasterPtr rst = NULL;
842
843 if (!is_valid_sample_type (sample_type))
844 return NULL;
845 if (!is_valid_pixel_type (pixel_type))
846 return NULL;
847 if (!check_raster_self_consistency (sample_type, pixel_type, num_samples))
848 return NULL;
849 if (width < 1 || height < 1)
850 return NULL;
851 raster_size =
852 compute_raster_buffer_size (width, height, sample_type, num_samples);
853 if (bufpix == NULL)
854 return NULL;
855 if (raster_size != bufpix_size)
856 return NULL;
857 if (pixel_type == RL2_PIXEL_PALETTE && palette == NULL)
858 return NULL;
859 if (palette != NULL && pixel_type != RL2_PIXEL_PALETTE)
860 return NULL;
861 if (!check_raster_no_data
862 (pxl_no_data, sample_type, pixel_type, num_samples))
863 return NULL;
864 if (mask != NULL)
865 {
866 /* checking the mask size */
867 if (width * height != (unsigned int) mask_size)
868 return NULL;
869 p = mask;
870 for (row = 0; row < height; row++)
871 {
872 /* checking if sample doesn't exceed the max value */
873 for (col = 0; col < width; col++)
874 {
875 if (*p++ > 1)
876 return NULL;
877 }
878 }
879 }
880 if (palette != NULL)
881 {
882 /* checking the Palette for validity */
883 unsigned short max_palette;
884 rl2_get_palette_entries (palette, &max_palette);
885 p = bufpix;
886 for (row = 0; row < height; row++)
887 {
888 for (col = 0; col < width; col++)
889 {
890 if (*p++ >= max_palette)
891 return NULL;
892 }
893 }
894 }
895 switch (sample_type)
896 {
897 /* checking if sample doesn't exceed the max value for #bits */
898 case RL2_SAMPLE_1_BIT:
899 p = bufpix;
900 for (row = 0; row < height; row++)
901 {
902 for (col = 0; col < width; col++)
903 {
904 if (*p++ > 1)
905 return NULL;
906 }
907 }
908 break;
909 case RL2_SAMPLE_2_BIT:
910 p = bufpix;
911 for (row = 0; row < height; row++)
912 {
913 for (col = 0; col < width; col++)
914 {
915 if (*p++ > 3)
916 return NULL;
917 }
918 }
919 break;
920 case RL2_SAMPLE_4_BIT:
921 p = bufpix;
922 for (row = 0; row < height; row++)
923 {
924 for (col = 0; col < width; col++)
925 {
926 if (*p++ > 15)
927 return NULL;
928 }
929 }
930 break;
931 };
932
933 rst = malloc (sizeof (rl2PrivRaster));
934 if (rst == NULL)
935 return NULL;
936 rst->sampleType = sample_type;
937 rst->pixelType = pixel_type;
938 rst->nBands = num_samples;
939 rst->width = width;
940 rst->height = height;
941 rst->Srid = RL2_GEOREFERENCING_NONE;
942 rst->minX = 0.0;
943 rst->minY = 0.0;
944 rst->maxX = width;
945 rst->maxY = height;
946 rst->rasterBuffer = bufpix;
947 rst->maskBuffer = mask;
948 rst->Palette = (rl2PrivPalettePtr) palette;
949 rst->noData = pxl_no_data;
950 return (rl2RasterPtr) rst;
951 }
952
953 RL2_DECLARE void
rl2_destroy_raster(rl2RasterPtr ptr)954 rl2_destroy_raster (rl2RasterPtr ptr)
955 {
956 /* memory cleanup - destroying a Raster object */
957 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
958 if (rst == NULL)
959 return;
960 if (rst->rasterBuffer != NULL)
961 free (rst->rasterBuffer);
962 if (rst->maskBuffer != NULL)
963 free (rst->maskBuffer);
964 if (rst->Palette != NULL)
965 rl2_destroy_palette ((rl2PalettePtr) (rst->Palette));
966 if (rst->noData != NULL)
967 rl2_destroy_pixel ((rl2PixelPtr) (rst->noData));
968 free (rst);
969 }
970
971 RL2_DECLARE int
rl2_set_raster_no_data(rl2RasterPtr ptr,rl2PixelPtr no_data)972 rl2_set_raster_no_data (rl2RasterPtr ptr, rl2PixelPtr no_data)
973 {
974 /* explicitly sets the Raster NoData pixel */
975 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
976 rl2PrivPixelPtr pxl_no_data = (rl2PrivPixelPtr) no_data;
977 if (rst == NULL)
978 return RL2_ERROR;
979 if (!check_raster_no_data
980 (pxl_no_data, rst->sampleType, rst->pixelType, rst->nBands))
981 return RL2_ERROR;
982 if (rst->noData != NULL)
983 rl2_destroy_pixel ((rl2PixelPtr) (rst->noData));
984 rst->noData = pxl_no_data;
985 return RL2_OK;
986 }
987
988 RL2_DECLARE rl2PixelPtr
rl2_get_raster_no_data(rl2RasterPtr ptr)989 rl2_get_raster_no_data (rl2RasterPtr ptr)
990 {
991 /* return the Raster NoData pixel (if any) */
992 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
993 if (rst == NULL)
994 return NULL;
995 return (rl2PixelPtr) (rst->noData);
996 }
997
998 RL2_DECLARE int
rl2_get_raster_type(rl2RasterPtr ptr,unsigned char * sample_type,unsigned char * pixel_type,unsigned char * num_bands)999 rl2_get_raster_type (rl2RasterPtr ptr, unsigned char *sample_type,
1000 unsigned char *pixel_type, unsigned char *num_bands)
1001 {
1002 /* return the Raster type */
1003 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1004 if (rst == NULL)
1005 return RL2_ERROR;
1006 *sample_type = rst->sampleType;
1007 *pixel_type = rst->pixelType;
1008 *num_bands = rst->nBands;
1009 return RL2_OK;
1010 }
1011
1012 RL2_DECLARE int
rl2_get_raster_size(rl2RasterPtr ptr,unsigned int * width,unsigned int * height)1013 rl2_get_raster_size (rl2RasterPtr ptr, unsigned int *width,
1014 unsigned int *height)
1015 {
1016 /* return the Raster width and height */
1017 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1018 if (rst == NULL)
1019 return RL2_ERROR;
1020 *width = rst->width;
1021 *height = rst->height;
1022 return RL2_OK;
1023 }
1024
1025 RL2_DECLARE int
rl2_get_raster_srid(rl2RasterPtr ptr,int * srid)1026 rl2_get_raster_srid (rl2RasterPtr ptr, int *srid)
1027 {
1028 /* return the Raster SRID */
1029 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1030 if (rst == NULL)
1031 return RL2_ERROR;
1032 *srid = rst->Srid;
1033 return RL2_OK;
1034 }
1035
1036 RL2_DECLARE int
rl2_get_raster_extent(rl2RasterPtr ptr,double * minX,double * minY,double * maxX,double * maxY)1037 rl2_get_raster_extent (rl2RasterPtr ptr, double *minX, double *minY,
1038 double *maxX, double *maxY)
1039 {
1040 /* return the Raster Min X coord */
1041 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1042 if (rst == NULL)
1043 return RL2_ERROR;
1044 if (rst->Srid == RL2_GEOREFERENCING_NONE)
1045 {
1046 *minX = 0.0;
1047 *minY = 0.0;
1048 *maxX = rst->width;
1049 *maxY = rst->height;
1050 return RL2_OK;
1051 }
1052 *minX = rst->minX;
1053 *minY = rst->minY;
1054 *maxX = rst->maxX;
1055 *maxY = rst->maxY;
1056 return RL2_OK;
1057 }
1058
1059 RL2_DECLARE gaiaGeomCollPtr
rl2_get_raster_bbox(rl2RasterPtr ptr)1060 rl2_get_raster_bbox (rl2RasterPtr ptr)
1061 {
1062 /* return the Raster BBox [envelope] */
1063 gaiaGeomCollPtr geom;
1064 gaiaPolygonPtr pg;
1065 gaiaRingPtr rng;
1066 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1067 if (rst == NULL)
1068 return NULL;
1069 if (rst->Srid == RL2_GEOREFERENCING_NONE)
1070 return NULL;
1071 geom = gaiaAllocGeomColl ();
1072 geom->Srid = rst->Srid;
1073 pg = gaiaAddPolygonToGeomColl (geom, 5, 0);
1074 rng = pg->Exterior;
1075 gaiaSetPoint (rng->Coords, 0, rst->minX, rst->minY);
1076 gaiaSetPoint (rng->Coords, 1, rst->maxX, rst->minY);
1077 gaiaSetPoint (rng->Coords, 2, rst->maxX, rst->maxY);
1078 gaiaSetPoint (rng->Coords, 3, rst->minX, rst->maxY);
1079 gaiaSetPoint (rng->Coords, 4, rst->minX, rst->minY);
1080 return geom;
1081 }
1082
1083 RL2_DECLARE int
rl2_get_raster_resolution(rl2RasterPtr ptr,double * hResolution,double * vResolution)1084 rl2_get_raster_resolution (rl2RasterPtr ptr, double *hResolution,
1085 double *vResolution)
1086 {
1087 /* return the Raster resolution */
1088 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1089 if (rst == NULL)
1090 return RL2_ERROR;
1091 if (rst->Srid == RL2_GEOREFERENCING_NONE)
1092 return RL2_ERROR;
1093 *hResolution = rst->hResolution;
1094 *vResolution = rst->vResolution;
1095 return RL2_OK;
1096 }
1097
1098 RL2_DECLARE rl2PalettePtr
rl2_get_raster_palette(rl2RasterPtr ptr)1099 rl2_get_raster_palette (rl2RasterPtr ptr)
1100 {
1101 /* return a pointer to the Raster palette */
1102 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1103 if (rst == NULL)
1104 return NULL;
1105 return (rl2PalettePtr) (rst->Palette);
1106 }
1107
1108 RL2_DECLARE int
rl2_raster_georeference_center(rl2RasterPtr ptr,int srid,double horz_res,double vert_res,double cx,double cy)1109 rl2_raster_georeference_center (rl2RasterPtr ptr, int srid, double horz_res,
1110 double vert_res, double cx, double cy)
1111 {
1112 /* setting the Raster's georeferencing infos - Center Point */
1113 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1114 double hExt;
1115 double vExt;
1116 if (rst == NULL)
1117 return RL2_ERROR;
1118 rst->Srid = srid;
1119 rst->hResolution = horz_res;
1120 rst->vResolution = vert_res;
1121 hExt = horz_res * (double) (rst->width) / 2.0;
1122 vExt = vert_res * (double) (rst->height) / 2.0;
1123 rst->minX = cx - hExt;
1124 rst->minY = cy - vExt;
1125 rst->maxX = cx + hExt;
1126 rst->maxY = cy + vExt;
1127 return RL2_OK;
1128 }
1129
1130 RL2_DECLARE int
rl2_raster_georeference_upper_left(rl2RasterPtr ptr,int srid,double horz_res,double vert_res,double x,double y)1131 rl2_raster_georeference_upper_left (rl2RasterPtr ptr, int srid, double horz_res,
1132 double vert_res, double x, double y)
1133 {
1134 /* setting the Raster's georeferencing infos - UpperLeft corner */
1135 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1136 double hExt;
1137 double vExt;
1138 if (rst == NULL)
1139 return RL2_ERROR;
1140 rst->Srid = srid;
1141 rst->hResolution = horz_res;
1142 rst->vResolution = vert_res;
1143 hExt = horz_res * (double) (rst->width);
1144 vExt = vert_res * (double) (rst->height);
1145 rst->minX = x;
1146 rst->minY = y - vExt;
1147 rst->maxX = x + hExt;
1148 rst->maxY = y;
1149 return RL2_OK;
1150 }
1151
1152 RL2_DECLARE int
rl2_raster_georeference_upper_right(rl2RasterPtr ptr,int srid,double horz_res,double vert_res,double x,double y)1153 rl2_raster_georeference_upper_right (rl2RasterPtr ptr, int srid,
1154 double horz_res, double vert_res, double x,
1155 double y)
1156 {
1157 /* setting the Raster's georeferencing infos - UpperRight corner */
1158 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1159 double hExt;
1160 double vExt;
1161 if (rst == NULL)
1162 return RL2_ERROR;
1163 rst->Srid = srid;
1164 rst->hResolution = horz_res;
1165 rst->vResolution = vert_res;
1166 hExt = horz_res * (double) (rst->width);
1167 vExt = vert_res * (double) (rst->height);
1168 rst->minX = x - hExt;
1169 rst->minY = y - vExt;
1170 rst->maxX = x;
1171 rst->maxY = y;
1172 return RL2_OK;
1173 }
1174
1175 RL2_DECLARE int
rl2_raster_georeference_lower_left(rl2RasterPtr ptr,int srid,double horz_res,double vert_res,double x,double y)1176 rl2_raster_georeference_lower_left (rl2RasterPtr ptr, int srid, double horz_res,
1177 double vert_res, double x, double y)
1178 {
1179 /* setting the Raster's georeferencing infos - LowerLeft corner */
1180 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1181 double hExt;
1182 double vExt;
1183 if (rst == NULL)
1184 return RL2_ERROR;
1185 rst->Srid = srid;
1186 rst->hResolution = horz_res;
1187 rst->vResolution = vert_res;
1188 hExt = horz_res * (double) (rst->width);
1189 vExt = vert_res * (double) (rst->height);
1190 rst->minX = x;
1191 rst->minY = y;
1192 rst->maxX = x + hExt;
1193 rst->maxY = y + vExt;
1194 return RL2_OK;
1195 }
1196
1197 RL2_DECLARE int
rl2_raster_georeference_lower_right(rl2RasterPtr ptr,int srid,double horz_res,double vert_res,double x,double y)1198 rl2_raster_georeference_lower_right (rl2RasterPtr ptr, int srid,
1199 double horz_res, double vert_res, double x,
1200 double y)
1201 {
1202 /* setting the Raster's georeferencing infos - LowerRight corner */
1203 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1204 double hExt;
1205 double vExt;
1206 if (rst == NULL)
1207 return RL2_ERROR;
1208 rst->Srid = srid;
1209 rst->hResolution = horz_res;
1210 rst->vResolution = vert_res;
1211 hExt = horz_res * (double) (rst->width);
1212 vExt = vert_res * (double) (rst->height);
1213 rst->minX = x - hExt;
1214 rst->minY = y;
1215 rst->maxX = x;
1216 rst->maxY = y + vExt;
1217 return RL2_OK;
1218 }
1219
1220 RL2_DECLARE int
rl2_raster_georeference_frame(rl2RasterPtr ptr,int srid,double min_x,double min_y,double max_x,double max_y)1221 rl2_raster_georeference_frame (rl2RasterPtr ptr, int srid, double min_x,
1222 double min_y, double max_x, double max_y)
1223 {
1224 /* setting the Raster's georeferencing infos - LowerRight corner */
1225 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
1226 double hExt;
1227 double vExt;
1228 double horz_res;
1229 double vert_res;
1230 if (rst == NULL)
1231 return RL2_ERROR;
1232 if (max_x <= min_x)
1233 return RL2_ERROR;
1234 if (max_y <= min_y)
1235 return RL2_ERROR;
1236
1237 rst->Srid = srid;
1238 rst->minX = min_x;
1239 rst->minY = min_y;
1240 rst->maxX = max_x;
1241 rst->maxY = max_y;
1242 hExt = max_x - min_x;
1243 vExt = max_y - min_y;
1244 horz_res = hExt / (double) (rst->width);
1245 vert_res = vExt / (double) (rst->height);
1246 rst->hResolution = horz_res;
1247 rst->vResolution = vert_res;
1248 hExt = horz_res * (double) (rst->width);
1249 vExt = vert_res * (double) (rst->height);
1250 return RL2_OK;
1251 }
1252
1253 RL2_DECLARE rl2PalettePtr
rl2_create_palette(int num_entries)1254 rl2_create_palette (int num_entries)
1255 {
1256 /* allocating and initializing a Palette object */
1257 int i;
1258 rl2PrivPalettePtr plt = NULL;
1259 if (num_entries < 0 || num_entries > 256)
1260 return NULL;
1261
1262 plt = malloc (sizeof (rl2PrivPalette));
1263 if (plt == NULL)
1264 return NULL;
1265 plt->nEntries = num_entries;
1266 if (num_entries == 0)
1267 {
1268 plt->entries = NULL;
1269 return (rl2PalettePtr) plt;
1270 }
1271 plt->entries = malloc (sizeof (rl2PrivPaletteEntry) * num_entries);
1272 if (plt->entries == NULL)
1273 {
1274 free (plt);
1275 return NULL;
1276 }
1277 for (i = 0; i < num_entries; i++)
1278 {
1279 /* setting all entries as BLACK full opaque */
1280 rl2PrivPaletteEntryPtr entry = plt->entries + i;
1281 entry->red = 0;
1282 entry->green = 0;
1283 entry->blue = 0;
1284 }
1285 return (rl2PalettePtr) plt;
1286 }
1287
1288 RL2_DECLARE void
rl2_destroy_palette(rl2PalettePtr ptr)1289 rl2_destroy_palette (rl2PalettePtr ptr)
1290 {
1291 /* memory cleanup - destroying a Palette object */
1292 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) ptr;
1293 if (plt == NULL)
1294 return;
1295 if (plt->entries != NULL)
1296 free (plt->entries);
1297 free (plt);
1298 }
1299
1300 RL2_DECLARE rl2PalettePtr
rl2_clone_palette(rl2PalettePtr in)1301 rl2_clone_palette (rl2PalettePtr in)
1302 {
1303 /* cloning a Palette object */
1304 rl2PrivPalettePtr plt_in = (rl2PrivPalettePtr) in;
1305 rl2PalettePtr out;
1306 rl2PrivPalettePtr plt_out;
1307 int i;
1308 if (in == NULL)
1309 return NULL;
1310 out = rl2_create_palette (plt_in->nEntries);
1311 plt_out = (rl2PrivPalettePtr) out;
1312 for (i = 0; i < plt_out->nEntries; i++)
1313 {
1314 rl2PrivPaletteEntryPtr entry_in = plt_in->entries + i;
1315 rl2PrivPaletteEntryPtr entry_out = plt_out->entries + i;
1316 entry_out->red = entry_in->red;
1317 entry_out->green = entry_in->green;
1318 entry_out->blue = entry_in->blue;
1319 }
1320 return out;
1321 }
1322
1323 RL2_DECLARE int
rl2_compare_palettes(rl2PalettePtr palette_1,rl2PalettePtr palette_2)1324 rl2_compare_palettes (rl2PalettePtr palette_1, rl2PalettePtr palette_2)
1325 {
1326 /* comparing two Palette objects */
1327 rl2PrivPalettePtr plt_1 = (rl2PrivPalettePtr) palette_1;
1328 rl2PrivPalettePtr plt_2 = (rl2PrivPalettePtr) palette_2;
1329 int i;
1330 if (plt_1 == NULL || plt_2 == NULL)
1331 return 0;
1332 if (plt_1->nEntries != plt_2->nEntries)
1333 return 0;
1334 for (i = 0; i < plt_2->nEntries; i++)
1335 {
1336 rl2PrivPaletteEntryPtr entry_1 = plt_1->entries + i;
1337 rl2PrivPaletteEntryPtr entry_2 = plt_2->entries + i;
1338 if (entry_1->red != entry_2->red)
1339 return 0;
1340 if (entry_1->green != entry_2->green)
1341 return 0;
1342 if (entry_1->blue != entry_2->blue)
1343 return 0;
1344 }
1345 return 1;
1346 }
1347
1348 static int
check_monochrome(int max,unsigned char * red,unsigned char * green,unsigned char * blue)1349 check_monochrome (int max, unsigned char *red, unsigned char *green,
1350 unsigned char *blue)
1351 {
1352 /* testing for a MONOCHROME palette */
1353 if (max != 2)
1354 return 0;
1355 if (*(red + 0) != 255 || *(green + 0) != 255 || *(blue + 0) != 255)
1356 return 0;
1357 if (*(red + 1) != 0 || *(green + 1) != 0 || *(blue + 1) != 0)
1358 return 0;
1359 return 1;
1360 }
1361
1362 static int
check_gray(int max,unsigned char * red,unsigned char * green,unsigned char * blue)1363 check_gray (int max, unsigned char *red, unsigned char *green,
1364 unsigned char *blue)
1365 {
1366 /* testing for a GRAYSCALE palette */
1367 int i;
1368 if (max == 4)
1369 {
1370 /* Gray4 */
1371 if (*(red + 0) != 0 || *(green + 0) != 0 || *(blue + 0) != 0)
1372 return 0;
1373 if (*(red + 1) != 86 || *(green + 1) != 86 || *(blue + 1) != 86)
1374 return 0;
1375 if (*(red + 2) != 170 || *(green + 2) != 170 || *(blue + 2) != 170)
1376 return 0;
1377 if (*(red + 3) != 255 || *(green + 3) != 255 || *(blue + 3) != 255)
1378 return 0;
1379 return 1;
1380 }
1381 if (max == 16)
1382 {
1383 /* Gray16 */
1384 if (*(red + 0) != 0 || *(green + 0) != 0 || *(blue + 0) != 0)
1385 return 0;
1386 if (*(red + 1) != 17 || *(green + 1) != 17 || *(blue + 1) != 17)
1387 return 0;
1388 if (*(red + 2) != 34 || *(green + 2) != 34 || *(blue + 2) != 34)
1389 return 0;
1390 if (*(red + 3) != 51 || *(green + 3) != 51 || *(blue + 3) != 51)
1391 return 0;
1392 if (*(red + 4) != 68 || *(green + 4) != 68 || *(blue + 4) != 68)
1393 return 0;
1394 if (*(red + 5) != 85 || *(green + 5) != 85 || *(blue + 5) != 85)
1395 return 0;
1396 if (*(red + 6) != 102 || *(green + 6) != 102 || *(blue + 6) != 102)
1397 return 0;
1398 if (*(red + 7) != 119 || *(green + 7) != 119 || *(blue + 7) != 119)
1399 return 0;
1400 if (*(red + 8) != 137 || *(green + 8) != 137 || *(blue + 8) != 137)
1401 return 0;
1402 if (*(red + 9) != 154 || *(green + 9) != 154 || *(blue + 9) != 154)
1403 return 0;
1404 if (*(red + 10) != 171 || *(green + 10) != 171 || *(blue + 10) != 171)
1405 return 0;
1406 if (*(red + 11) != 188 || *(green + 11) != 188 || *(blue + 11) != 188)
1407 return 0;
1408 if (*(red + 12) != 205 || *(green + 12) != 205 || *(blue + 12) != 205)
1409 return 0;
1410 if (*(red + 13) != 222 || *(green + 13) != 222 || *(blue + 13) != 222)
1411 return 0;
1412 if (*(red + 14) != 239 || *(green + 14) != 239 || *(blue + 14) != 239)
1413 return 0;
1414 if (*(red + 15) != 255 || *(green + 15) != 255 || *(blue + 15) != 255)
1415 return 0;
1416 return 1;
1417 }
1418 if (max == 256)
1419 {
1420 /* Gray256 */
1421 for (i = 0; i < max; i++)
1422 {
1423 if (*(red + i) != i || *(green + i) != i || *(blue + i) != i)
1424 return 0;
1425 }
1426 return 1;
1427 }
1428 return 0;
1429 }
1430
1431 RL2_DECLARE int
rl2_get_palette_type(rl2PalettePtr ptr,unsigned char * sample_type,unsigned char * pixel_type)1432 rl2_get_palette_type (rl2PalettePtr ptr, unsigned char *sample_type,
1433 unsigned char *pixel_type)
1434 {
1435 /* retrieving the palette type */
1436 unsigned char red[256];
1437 unsigned char green[256];
1438 unsigned char blue[256];
1439 int max = 0;
1440 int index;
1441 int i;
1442 int already_defined;
1443 rl2PrivPaletteEntryPtr entry;
1444 rl2PrivPalettePtr palette = (rl2PrivPalettePtr) ptr;
1445 if (palette == NULL)
1446 return RL2_ERROR;
1447
1448 for (index = 0; index < palette->nEntries; index++)
1449 {
1450 /* normalizing the palette, so to avoid duplicate colors */
1451 already_defined = 0;
1452 entry = palette->entries + index;
1453 for (i = 0; i < max; i++)
1454 {
1455 if (entry->red == red[i] && entry->green == green[i]
1456 && entry->blue == blue[i])
1457 {
1458 already_defined = 1;
1459 break;
1460 }
1461 }
1462 if (!already_defined)
1463 {
1464 /* inserting a normalized color */
1465 red[max] = entry->red;
1466 green[max] = entry->green;
1467 blue[max] = entry->blue;
1468 max++;
1469 }
1470 }
1471 if (max <= 2)
1472 *sample_type = RL2_SAMPLE_1_BIT;
1473 else if (max <= 4)
1474 *sample_type = RL2_SAMPLE_2_BIT;
1475 else if (max <= 16)
1476 *sample_type = RL2_SAMPLE_4_BIT;
1477 else
1478 *sample_type = RL2_SAMPLE_UINT8;
1479 *pixel_type = RL2_PIXEL_PALETTE;
1480 if (check_monochrome (max, red, green, blue))
1481 *pixel_type = RL2_PIXEL_MONOCHROME;
1482 else if (check_gray (max, red, green, blue))
1483 *pixel_type = RL2_PIXEL_GRAYSCALE;
1484 return RL2_OK;
1485 }
1486
1487 RL2_DECLARE int
rl2_set_palette_color(rl2PalettePtr ptr,int index,unsigned char r,unsigned char g,unsigned char b)1488 rl2_set_palette_color (rl2PalettePtr ptr, int index, unsigned char r,
1489 unsigned char g, unsigned char b)
1490 {
1491 /* setting a Palette entry */
1492 rl2PrivPaletteEntryPtr entry;
1493 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) ptr;
1494 if (plt == NULL)
1495 return RL2_ERROR;
1496 if (index < 0 || index >= plt->nEntries)
1497 return RL2_ERROR;
1498 entry = plt->entries + index;
1499 entry->red = r;
1500 entry->green = g;
1501 entry->blue = b;
1502 return RL2_OK;
1503 }
1504
1505 RL2_DECLARE int
rl2_get_palette_index(rl2PalettePtr ptr,unsigned char * index,unsigned char r,unsigned char g,unsigned char b)1506 rl2_get_palette_index (rl2PalettePtr ptr, unsigned char *index, unsigned char r,
1507 unsigned char g, unsigned char b)
1508 {
1509 /* finding the index corresponding to the given color (if any) */
1510 int i;
1511 rl2PrivPaletteEntryPtr entry;
1512 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) ptr;
1513 if (plt == NULL)
1514 return RL2_ERROR;
1515 for (i = 0; i < plt->nEntries; i++)
1516 {
1517 entry = plt->entries + i;
1518 if (entry->red == r && entry->green == g && entry->blue == b)
1519 {
1520 *index = i;
1521 return RL2_OK;
1522 }
1523 }
1524 return RL2_ERROR;
1525 }
1526
1527 static int
parse_hex(unsigned char hi,unsigned char lo,unsigned char * x)1528 parse_hex (unsigned char hi, unsigned char lo, unsigned char *x)
1529 {
1530 /* parsing an Hex Byte */
1531 unsigned char res;
1532 switch (hi)
1533 {
1534 case '0':
1535 res = 0;
1536 break;
1537 case '1':
1538 res = 16;
1539 break;
1540 case '2':
1541 res = 2 * 16;
1542 break;
1543 case '3':
1544 res = 3 * 16;
1545 break;
1546 case '4':
1547 res = 4 * 16;
1548 break;
1549 case '5':
1550 res = 5 * 16;
1551 break;
1552 case '6':
1553 res = 6 * 16;
1554 break;
1555 case '7':
1556 res = 7 * 16;
1557 break;
1558 case '8':
1559 res = 8 * 16;
1560 break;
1561 case '9':
1562 res = 9 * 16;
1563 break;
1564 case 'a':
1565 case 'A':
1566 res = 10 * 16;
1567 break;
1568 case 'b':
1569 case 'B':
1570 res = 11 * 16;
1571 break;
1572 case 'c':
1573 case 'C':
1574 res = 12 * 16;
1575 break;
1576 case 'd':
1577 case 'D':
1578 res = 13 * 16;
1579 break;
1580 case 'e':
1581 case 'E':
1582 res = 14 * 16;
1583 break;
1584 case 'f':
1585 case 'F':
1586 res = 15 * 16;
1587 break;
1588 default:
1589 return RL2_ERROR;
1590 };
1591 switch (lo)
1592 {
1593 case '0':
1594 break;
1595 case '1':
1596 res += 1;
1597 break;
1598 case '2':
1599 res += 2;
1600 break;
1601 case '3':
1602 res += 3;
1603 break;
1604 case '4':
1605 res += 4;
1606 break;
1607 case '5':
1608 res += 5;
1609 break;
1610 case '6':
1611 res += 6;
1612 break;
1613 case '7':
1614 res += 7;
1615 break;
1616 case '8':
1617 res += 8;
1618 break;
1619 case '9':
1620 res += 9;
1621 break;
1622 case 'a':
1623 case 'A':
1624 res += 10;
1625 break;
1626 case 'b':
1627 case 'B':
1628 res += 11;
1629 break;
1630 case 'c':
1631 case 'C':
1632 res += 12;
1633 break;
1634 case 'd':
1635 case 'D':
1636 res += 13;
1637 break;
1638 case 'e':
1639 case 'E':
1640 res += 14;
1641 break;
1642 case 'f':
1643 case 'F':
1644 res += 15;
1645 break;
1646 default:
1647 return RL2_ERROR;
1648 };
1649 *x = res;
1650 return RL2_OK;
1651 }
1652
1653 static int
parse_hex_rgb(const char * hex,unsigned char * r,unsigned char * g,unsigned char * b)1654 parse_hex_rgb (const char *hex, unsigned char *r, unsigned char *g,
1655 unsigned char *b)
1656 {
1657 /* parsing an Hex RGB */
1658 if (parse_hex (*(hex + 0), *(hex + 1), r) != RL2_OK)
1659 goto error;
1660 if (parse_hex (*(hex + 2), *(hex + 3), g) != RL2_OK)
1661 goto error;
1662 if (parse_hex (*(hex + 4), *(hex + 5), b) != RL2_OK)
1663 goto error;
1664 return RL2_OK;
1665 error:
1666 *r = 0;
1667 *g = 0;
1668 *b = 0;
1669 return RL2_ERROR;
1670 }
1671
1672 RL2_DECLARE int
rl2_parse_hexrgb(const char * hex,unsigned char * red,unsigned char * green,unsigned char * blue)1673 rl2_parse_hexrgb (const char *hex, unsigned char *red, unsigned char *green,
1674 unsigned char *blue)
1675 {
1676 /* setting a Palette entry */
1677 if (hex == NULL)
1678 return RL2_ERROR;
1679 if (strlen (hex) != 7)
1680 return RL2_ERROR;
1681 if (*hex != '#')
1682 return RL2_ERROR;
1683 if (parse_hex_rgb (hex + 1, red, green, blue) != RL2_OK)
1684 return RL2_ERROR;
1685 return RL2_OK;
1686 }
1687
1688 RL2_DECLARE int
rl2_set_palette_hexrgb(rl2PalettePtr ptr,int index,const char * hex)1689 rl2_set_palette_hexrgb (rl2PalettePtr ptr, int index, const char *hex)
1690 {
1691 /* setting a Palette entry */
1692 unsigned char r;
1693 unsigned char g;
1694 unsigned char b;
1695 rl2PrivPaletteEntryPtr entry;
1696 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) ptr;
1697 if (plt == NULL)
1698 return RL2_ERROR;
1699 if (index < 0 || index >= plt->nEntries)
1700 return RL2_ERROR;
1701 if (hex == NULL)
1702 return RL2_ERROR;
1703 if (strlen (hex) != 7)
1704 return RL2_ERROR;
1705 if (*hex != '#')
1706 return RL2_ERROR;
1707 if (parse_hex_rgb (hex + 1, &r, &g, &b) != RL2_OK)
1708 return RL2_ERROR;
1709 entry = plt->entries + index;
1710 entry->red = r;
1711 entry->green = g;
1712 entry->blue = b;
1713 return RL2_OK;
1714 }
1715
1716 RL2_DECLARE int
rl2_get_palette_entries(rl2PalettePtr ptr,unsigned short * num_entries)1717 rl2_get_palette_entries (rl2PalettePtr ptr, unsigned short *num_entries)
1718 {
1719 /* return the Palette entries count */
1720 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) ptr;
1721 if (plt == NULL)
1722 return RL2_ERROR;
1723 *num_entries = plt->nEntries;
1724 return RL2_OK;
1725 }
1726
1727 RL2_DECLARE int
rl2_get_palette_colors(rl2PalettePtr ptr,unsigned short * num_entries,unsigned char ** r,unsigned char ** g,unsigned char ** b)1728 rl2_get_palette_colors (rl2PalettePtr ptr, unsigned short *num_entries,
1729 unsigned char **r, unsigned char **g, unsigned char **b)
1730 {
1731 /* return the Palette colors */
1732 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) ptr;
1733 unsigned char *red = NULL;
1734 unsigned char *green = NULL;
1735 unsigned char *blue = NULL;
1736 int i;
1737 *num_entries = 0;
1738 *r = NULL;
1739 *g = NULL;
1740 *b = NULL;
1741 if (plt == NULL)
1742 return RL2_ERROR;
1743 red = malloc (plt->nEntries);
1744 green = malloc (plt->nEntries);
1745 blue = malloc (plt->nEntries);
1746 if (red == NULL || green == NULL || blue == NULL)
1747 {
1748 if (red != NULL)
1749 free (red);
1750 if (green != NULL)
1751 free (green);
1752 if (blue != NULL)
1753 free (blue);
1754 return RL2_ERROR;
1755 }
1756 for (i = 0; i < plt->nEntries; i++)
1757 {
1758 rl2PrivPaletteEntryPtr entry = plt->entries + i;
1759 *(red + i) = entry->red;
1760 *(green + i) = entry->green;
1761 *(blue + i) = entry->blue;
1762 }
1763 *num_entries = plt->nEntries;
1764 *r = red;
1765 *g = green;
1766 *b = blue;
1767 return RL2_OK;
1768 }
1769
1770 RL2_DECLARE rl2PixelPtr
rl2_create_pixel(unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples)1771 rl2_create_pixel (unsigned char sample_type, unsigned char pixel_type,
1772 unsigned char num_samples)
1773 {
1774 /* allocating and initializing a Pixel object */
1775 int nBand;
1776 rl2PrivPixelPtr pxl = NULL;
1777 if (!is_valid_sample_type (sample_type))
1778 return NULL;
1779 if (!is_valid_pixel_type (pixel_type))
1780 return NULL;
1781 switch (pixel_type)
1782 {
1783 case RL2_PIXEL_MONOCHROME:
1784 case RL2_PIXEL_PALETTE:
1785 case RL2_PIXEL_GRAYSCALE:
1786 case RL2_PIXEL_DATAGRID:
1787 if (num_samples != 1)
1788 return NULL;
1789 break;
1790 case RL2_PIXEL_RGB:
1791 if (num_samples != 3)
1792 return NULL;
1793 break;
1794 case RL2_PIXEL_MULTIBAND:
1795 if (num_samples < 2)
1796 return NULL;
1797 break;
1798 };
1799
1800 pxl = malloc (sizeof (rl2PrivPixel));
1801 if (pxl == NULL)
1802 return NULL;
1803 pxl->sampleType = sample_type;
1804 pxl->pixelType = pixel_type;
1805 pxl->nBands = num_samples;
1806 pxl->isTransparent = 0;
1807 pxl->Samples = malloc (sizeof (rl2PrivSample) * num_samples);
1808 if (pxl->Samples == NULL)
1809 {
1810 free (pxl);
1811 return NULL;
1812 }
1813 for (nBand = 0; nBand < num_samples; nBand++)
1814 {
1815 /* initializing all samples as ZERO */
1816 rl2PrivSamplePtr sample = pxl->Samples + nBand;
1817 switch (sample_type)
1818 {
1819 case RL2_SAMPLE_1_BIT:
1820 case RL2_SAMPLE_2_BIT:
1821 case RL2_SAMPLE_4_BIT:
1822 case RL2_SAMPLE_UINT8:
1823 sample->uint8 = 0;
1824 break;
1825 case RL2_SAMPLE_INT8:
1826 sample->int8 = 0;
1827 break;
1828 case RL2_SAMPLE_INT16:
1829 sample->int16 = 0;
1830 break;
1831 case RL2_SAMPLE_UINT16:
1832 sample->uint16 = 0;
1833 break;
1834 case RL2_SAMPLE_INT32:
1835 sample->int32 = 0;
1836 break;
1837 case RL2_SAMPLE_UINT32:
1838 sample->uint32 = 0;
1839 break;
1840 case RL2_SAMPLE_FLOAT:
1841 sample->float32 = 0.0;
1842 break;
1843 case RL2_SAMPLE_DOUBLE:
1844 sample->float64 = 0.0;
1845 break;
1846 }
1847 }
1848 return (rl2PixelPtr) pxl;
1849 }
1850
1851 RL2_DECLARE rl2PixelPtr
rl2_clone_pixel(rl2PixelPtr org)1852 rl2_clone_pixel (rl2PixelPtr org)
1853 {
1854 /* cloning a Pixel object */
1855 int b;
1856 rl2PixelPtr dst;
1857 rl2PrivPixelPtr px_out;
1858 rl2PrivPixelPtr px_in = (rl2PrivPixelPtr) org;
1859 if (px_in == NULL)
1860 return NULL;
1861 dst = rl2_create_pixel (px_in->sampleType, px_in->pixelType, px_in->nBands);
1862 if (dst == NULL)
1863 return NULL;
1864 px_out = (rl2PrivPixelPtr) dst;
1865 for (b = 0; b < px_in->nBands; b++)
1866 {
1867 /* copying all samples */
1868 rl2PrivSamplePtr sample_in = px_in->Samples + b;
1869 rl2PrivSamplePtr sample_out = px_out->Samples + b;
1870 switch (px_in->sampleType)
1871 {
1872 case RL2_SAMPLE_1_BIT:
1873 case RL2_SAMPLE_2_BIT:
1874 case RL2_SAMPLE_4_BIT:
1875 case RL2_SAMPLE_UINT8:
1876 sample_out->uint8 = sample_in->uint8;
1877 break;
1878 case RL2_SAMPLE_INT8:
1879 sample_out->int8 = sample_in->int8;
1880 break;
1881 case RL2_SAMPLE_INT16:
1882 sample_out->int16 = sample_in->int16;
1883 break;
1884 case RL2_SAMPLE_UINT16:
1885 sample_out->uint16 = sample_in->uint16;
1886 break;
1887 case RL2_SAMPLE_INT32:
1888 sample_out->int32 = sample_in->int32;
1889 break;
1890 case RL2_SAMPLE_UINT32:
1891 sample_out->uint32 = sample_in->uint32;
1892 break;
1893 case RL2_SAMPLE_FLOAT:
1894 sample_out->float32 = sample_in->float32;
1895 break;
1896 case RL2_SAMPLE_DOUBLE:
1897 sample_out->float64 = sample_in->float64;
1898 break;
1899 }
1900 }
1901 return dst;
1902 }
1903
1904 RL2_DECLARE rl2PixelPtr
rl2_create_triple_band_pixel(rl2PixelPtr org,unsigned char red_band,unsigned char green_band,unsigned char blue_band)1905 rl2_create_triple_band_pixel (rl2PixelPtr org, unsigned char red_band,
1906 unsigned char green_band, unsigned char blue_band)
1907 {
1908 /* creating a new Pixel object by applying band composing */
1909 rl2PrivSamplePtr sample_in;
1910 rl2PrivSamplePtr sample_out;
1911 rl2PixelPtr dst;
1912 rl2PrivPixelPtr px_out;
1913 rl2PrivPixelPtr px_in = (rl2PrivPixelPtr) org;
1914 if (px_in == NULL)
1915 return NULL;
1916 if (px_in->sampleType != RL2_SAMPLE_UINT8
1917 && px_in->sampleType != RL2_SAMPLE_UINT16)
1918 return NULL;
1919 if (px_in->pixelType != RL2_PIXEL_RGB
1920 && px_in->pixelType != RL2_PIXEL_MULTIBAND)
1921 return NULL;
1922 if (red_band >= px_in->nBands)
1923 return NULL;
1924 if (green_band >= px_in->nBands)
1925 return NULL;
1926 if (blue_band >= px_in->nBands)
1927 return NULL;
1928 dst = rl2_create_pixel (px_in->sampleType, RL2_PIXEL_RGB, 3);
1929 if (dst == NULL)
1930 return NULL;
1931 px_out = (rl2PrivPixelPtr) dst;
1932 /* red band */
1933 sample_in = px_in->Samples + red_band;
1934 sample_out = px_out->Samples + 0;
1935 if (px_in->sampleType == RL2_SAMPLE_UINT16)
1936 sample_out->uint16 = sample_in->uint16;
1937 else
1938 sample_out->uint8 = sample_in->uint8;
1939 /* green band */
1940 sample_in = px_in->Samples + green_band;
1941 sample_out = px_out->Samples + 1;
1942 if (px_in->sampleType == RL2_SAMPLE_UINT16)
1943 sample_out->uint16 = sample_in->uint16;
1944 else
1945 sample_out->uint8 = sample_in->uint8;
1946 /* blue band */
1947 sample_in = px_in->Samples + blue_band;
1948 sample_out = px_out->Samples + 2;
1949 if (px_in->sampleType == RL2_SAMPLE_UINT16)
1950 sample_out->uint16 = sample_in->uint16;
1951 else
1952 sample_out->uint8 = sample_in->uint8;
1953 return dst;
1954 }
1955
1956 RL2_DECLARE rl2PixelPtr
rl2_create_mono_band_pixel(rl2PixelPtr org,unsigned char mono_band)1957 rl2_create_mono_band_pixel (rl2PixelPtr org, unsigned char mono_band)
1958 {
1959 /* creating a new Pixel object by applying band composing */
1960 rl2PrivSamplePtr sample_in;
1961 rl2PrivSamplePtr sample_out;
1962 rl2PixelPtr dst;
1963 rl2PrivPixelPtr px_out;
1964 rl2PrivPixelPtr px_in = (rl2PrivPixelPtr) org;
1965 if (px_in == NULL)
1966 return NULL;
1967 if (px_in->sampleType != RL2_SAMPLE_UINT8
1968 && px_in->sampleType != RL2_SAMPLE_UINT16)
1969 return NULL;
1970 if (px_in->pixelType != RL2_PIXEL_RGB
1971 && px_in->pixelType != RL2_PIXEL_MULTIBAND)
1972 return NULL;
1973 if (mono_band >= px_in->nBands)
1974 return NULL;
1975 if (px_in->sampleType == RL2_SAMPLE_UINT16)
1976 dst = rl2_create_pixel (RL2_SAMPLE_UINT16, RL2_PIXEL_DATAGRID, 1);
1977 else
1978 dst = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3);
1979 if (dst == NULL)
1980 return NULL;
1981 px_out = (rl2PrivPixelPtr) dst;
1982 /* mono band */
1983 sample_in = px_in->Samples + mono_band;
1984 sample_out = px_out->Samples + 0;
1985 if (px_in->sampleType == RL2_SAMPLE_UINT16)
1986 sample_out->uint16 = sample_in->uint16;
1987 else
1988 sample_out->uint8 = sample_in->uint8;
1989 return dst;
1990 }
1991
1992 RL2_DECLARE void
rl2_destroy_pixel(rl2PixelPtr ptr)1993 rl2_destroy_pixel (rl2PixelPtr ptr)
1994 {
1995 /* memory cleanup - destroying a Pixel object */
1996 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
1997 if (pxl == NULL)
1998 return;
1999 if (pxl->Samples != NULL)
2000 free (pxl->Samples);
2001 free (pxl);
2002 }
2003
2004 RL2_DECLARE int
rl2_compare_pixels(rl2PixelPtr pixel1,rl2PixelPtr pixel2)2005 rl2_compare_pixels (rl2PixelPtr pixel1, rl2PixelPtr pixel2)
2006 {
2007 /* comparing if two pixels are the same */
2008 int band;
2009 rl2PrivPixelPtr pxl1 = (rl2PrivPixelPtr) pixel1;
2010 rl2PrivPixelPtr pxl2 = (rl2PrivPixelPtr) pixel2;
2011 if (pxl1 == NULL || pxl2 == NULL)
2012 return RL2_ERROR;
2013 if (pxl1->sampleType != pxl2->sampleType)
2014 return RL2_ERROR;
2015 if (pxl1->pixelType != pxl2->pixelType)
2016 return RL2_ERROR;
2017 if (pxl1->nBands != pxl2->nBands)
2018 return RL2_ERROR;
2019 for (band = 0; band < pxl1->nBands; band++)
2020 {
2021 rl2PrivSamplePtr sample1 = pxl1->Samples + band;
2022 rl2PrivSamplePtr sample2 = pxl2->Samples + band;
2023 switch (pxl1->sampleType)
2024 {
2025 case RL2_SAMPLE_INT8:
2026 if (sample1->int8 != sample2->int8)
2027 return RL2_FALSE;
2028 break;
2029 case RL2_SAMPLE_1_BIT:
2030 case RL2_SAMPLE_2_BIT:
2031 case RL2_SAMPLE_4_BIT:
2032 case RL2_SAMPLE_UINT8:
2033 if (sample1->uint8 != sample2->uint8)
2034 return RL2_FALSE;
2035 break;
2036 case RL2_SAMPLE_INT16:
2037 if (sample1->int16 != sample2->int16)
2038 return RL2_FALSE;
2039 break;
2040 case RL2_SAMPLE_UINT16:
2041 if (sample1->uint16 != sample2->uint16)
2042 return RL2_FALSE;
2043 break;
2044 case RL2_SAMPLE_INT32:
2045 if (sample1->int32 != sample2->int32)
2046 return RL2_FALSE;
2047 break;
2048 case RL2_SAMPLE_UINT32:
2049 if (sample1->uint32 != sample2->uint32)
2050 return RL2_FALSE;
2051 break;
2052 case RL2_SAMPLE_FLOAT:
2053 if (sample1->float32 != sample2->float32)
2054 return RL2_FALSE;
2055 break;
2056 case RL2_SAMPLE_DOUBLE:
2057 if (sample1->float64 != sample2->float64)
2058 return RL2_FALSE;
2059 break;
2060 };
2061 }
2062 if (pxl1->isTransparent != pxl2->isTransparent)
2063 return RL2_FALSE;
2064 return RL2_TRUE;
2065 }
2066
2067
2068 RL2_DECLARE int
rl2_get_pixel_type(rl2PixelPtr ptr,unsigned char * sample_type,unsigned char * pixel_type,unsigned char * num_bands)2069 rl2_get_pixel_type (rl2PixelPtr ptr,
2070 unsigned char *sample_type,
2071 unsigned char *pixel_type, unsigned char *num_bands)
2072 {
2073 /* return the Pixel pixel type */
2074 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2075 if (pxl == NULL)
2076 return RL2_ERROR;
2077 *sample_type = pxl->sampleType;
2078 *pixel_type = pxl->pixelType;
2079 *num_bands = pxl->nBands;
2080 return RL2_OK;
2081 }
2082
2083 RL2_DECLARE int
rl2_get_pixel_sample_1bit(rl2PixelPtr ptr,unsigned char * sample)2084 rl2_get_pixel_sample_1bit (rl2PixelPtr ptr, unsigned char *sample)
2085 {
2086 /* get a Pixel/Sample value - 1-BIT */
2087 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2088 if (pxl == NULL)
2089 return RL2_ERROR;
2090 if (pxl->sampleType != RL2_SAMPLE_1_BIT)
2091 return RL2_ERROR;
2092 *sample = pxl->Samples->uint8;
2093 return RL2_OK;
2094 }
2095
2096 RL2_DECLARE int
rl2_set_pixel_sample_1bit(rl2PixelPtr ptr,unsigned char sample)2097 rl2_set_pixel_sample_1bit (rl2PixelPtr ptr, unsigned char sample)
2098 {
2099 /* set a Pixel/Sample value - 1-BIT */
2100 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2101 if (pxl == NULL)
2102 return RL2_ERROR;
2103 if (pxl->sampleType != RL2_SAMPLE_1_BIT)
2104 return RL2_ERROR;
2105 if (sample > 1)
2106 return RL2_ERROR;
2107 pxl->Samples->uint8 = sample;
2108 return RL2_OK;
2109 }
2110
2111 RL2_DECLARE int
rl2_get_pixel_sample_2bit(rl2PixelPtr ptr,unsigned char * sample)2112 rl2_get_pixel_sample_2bit (rl2PixelPtr ptr, unsigned char *sample)
2113 {
2114 /* get a Pixel/Sample value - 2-BIT */
2115 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2116 if (pxl == NULL)
2117 return RL2_ERROR;
2118 if (pxl->sampleType != RL2_SAMPLE_2_BIT)
2119 return RL2_ERROR;
2120 *sample = pxl->Samples->uint8;
2121 return RL2_OK;
2122 }
2123
2124 RL2_DECLARE int
rl2_set_pixel_sample_2bit(rl2PixelPtr ptr,unsigned char sample)2125 rl2_set_pixel_sample_2bit (rl2PixelPtr ptr, unsigned char sample)
2126 {
2127 /* set a Pixel/Sample value - 2-BIT */
2128 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2129 if (pxl == NULL)
2130 return RL2_ERROR;
2131 if (pxl->sampleType != RL2_SAMPLE_2_BIT)
2132 return RL2_ERROR;
2133 if (sample > 3)
2134 return RL2_ERROR;
2135 pxl->Samples->uint8 = sample;
2136 return RL2_OK;
2137 }
2138
2139 RL2_DECLARE int
rl2_get_pixel_sample_4bit(rl2PixelPtr ptr,unsigned char * sample)2140 rl2_get_pixel_sample_4bit (rl2PixelPtr ptr, unsigned char *sample)
2141 {
2142 /* get a Pixel/Sample value - 4-BIT */
2143 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2144 if (pxl == NULL)
2145 return RL2_ERROR;
2146 if (pxl->sampleType != RL2_SAMPLE_4_BIT)
2147 return RL2_ERROR;
2148 *sample = pxl->Samples->uint8;
2149 return RL2_OK;
2150 }
2151
2152 RL2_DECLARE int
rl2_set_pixel_sample_4bit(rl2PixelPtr ptr,unsigned char sample)2153 rl2_set_pixel_sample_4bit (rl2PixelPtr ptr, unsigned char sample)
2154 {
2155 /* set a Pixel/Sample value - 4-BIT */
2156 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2157 if (pxl == NULL)
2158 return RL2_ERROR;
2159 if (pxl->sampleType != RL2_SAMPLE_4_BIT)
2160 return RL2_ERROR;
2161 if (sample > 15)
2162 return RL2_ERROR;
2163 pxl->Samples->uint8 = sample;
2164 return RL2_OK;
2165 }
2166
2167 RL2_DECLARE int
rl2_get_pixel_sample_int8(rl2PixelPtr ptr,char * sample)2168 rl2_get_pixel_sample_int8 (rl2PixelPtr ptr, char *sample)
2169 {
2170 /* get a Pixel/Sample value - INT8 */
2171 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2172 if (pxl == NULL)
2173 return RL2_ERROR;
2174 if (pxl->sampleType != RL2_SAMPLE_INT8)
2175 return RL2_ERROR;
2176 *sample = pxl->Samples->int8;
2177 return RL2_OK;
2178 }
2179
2180 RL2_DECLARE int
rl2_set_pixel_sample_int8(rl2PixelPtr ptr,char sample)2181 rl2_set_pixel_sample_int8 (rl2PixelPtr ptr, char sample)
2182 {
2183 /* set a Pixel/Sample value - INT8 */
2184 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2185 if (pxl == NULL)
2186 return RL2_ERROR;
2187 if (pxl->sampleType != RL2_SAMPLE_INT8)
2188 return RL2_ERROR;
2189 pxl->Samples->int8 = sample;
2190 return RL2_OK;
2191 }
2192
2193 RL2_DECLARE int
rl2_get_pixel_sample_uint8(rl2PixelPtr ptr,int band,unsigned char * sample)2194 rl2_get_pixel_sample_uint8 (rl2PixelPtr ptr, int band, unsigned char *sample)
2195 {
2196 /* get a Pixel/Sample value - UINT8 */
2197 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2198 if (pxl == NULL)
2199 return RL2_ERROR;
2200 if (pxl->sampleType != RL2_SAMPLE_UINT8)
2201 return RL2_ERROR;
2202 if (band >= 0 && band < pxl->nBands)
2203 {
2204 rl2PrivSamplePtr smp = pxl->Samples + band;
2205 *sample = smp->uint8;
2206 return RL2_OK;
2207 }
2208 return RL2_ERROR;
2209 }
2210
2211 RL2_DECLARE int
rl2_set_pixel_sample_uint8(rl2PixelPtr ptr,int band,unsigned char sample)2212 rl2_set_pixel_sample_uint8 (rl2PixelPtr ptr, int band, unsigned char sample)
2213 {
2214 /* set a Pixel/Sample value - UINT8 */
2215 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2216 if (pxl == NULL)
2217 return RL2_ERROR;
2218 if (pxl->sampleType != RL2_SAMPLE_UINT8)
2219 return RL2_ERROR;
2220 if (band >= 0 && band < pxl->nBands)
2221 {
2222 rl2PrivSamplePtr smp = pxl->Samples + band;
2223 smp->uint8 = sample;
2224 return RL2_OK;
2225 }
2226 return RL2_ERROR;
2227 }
2228
2229 RL2_DECLARE int
rl2_get_pixel_sample_int16(rl2PixelPtr ptr,short * sample)2230 rl2_get_pixel_sample_int16 (rl2PixelPtr ptr, short *sample)
2231 {
2232 /* get a Pixel/Sample value - INT16 */
2233 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2234 if (pxl == NULL)
2235 return RL2_ERROR;
2236 if (pxl->sampleType != RL2_SAMPLE_INT16)
2237 return RL2_ERROR;
2238 *sample = pxl->Samples->int16;
2239 return RL2_OK;
2240 }
2241
2242 RL2_DECLARE int
rl2_set_pixel_sample_int16(rl2PixelPtr ptr,short sample)2243 rl2_set_pixel_sample_int16 (rl2PixelPtr ptr, short sample)
2244 {
2245 /* set a Pixel/Sample value - INT16 */
2246 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2247 if (pxl == NULL)
2248 return RL2_ERROR;
2249 if (pxl->sampleType != RL2_SAMPLE_INT16)
2250 return RL2_ERROR;
2251 pxl->Samples->int16 = sample;
2252 return RL2_OK;
2253 }
2254
2255 RL2_DECLARE int
rl2_get_pixel_sample_uint16(rl2PixelPtr ptr,int band,unsigned short * sample)2256 rl2_get_pixel_sample_uint16 (rl2PixelPtr ptr, int band, unsigned short *sample)
2257 {
2258 /* get a Pixel/Sample value - UINT16 */
2259 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2260 if (pxl == NULL)
2261 return RL2_ERROR;
2262 if (pxl->sampleType != RL2_SAMPLE_UINT16)
2263 return RL2_ERROR;
2264 if (band >= 0 && band < pxl->nBands)
2265 {
2266 rl2PrivSamplePtr smp = pxl->Samples + band;
2267 *sample = smp->uint16;
2268 return RL2_OK;
2269 }
2270 return RL2_ERROR;
2271 }
2272
2273 RL2_DECLARE int
rl2_set_pixel_sample_uint16(rl2PixelPtr ptr,int band,unsigned short sample)2274 rl2_set_pixel_sample_uint16 (rl2PixelPtr ptr, int band, unsigned short sample)
2275 {
2276 /* set a Pixel/Sample value - UINT16 */
2277 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2278 if (pxl == NULL)
2279 return RL2_ERROR;
2280 if (pxl->sampleType != RL2_SAMPLE_UINT16)
2281 return RL2_ERROR;
2282 if (band >= 0 && band < pxl->nBands)
2283 {
2284 rl2PrivSamplePtr smp = pxl->Samples + band;
2285 smp->uint16 = sample;
2286 return RL2_OK;
2287 }
2288 return RL2_ERROR;
2289 }
2290
2291 RL2_DECLARE int
rl2_get_pixel_sample_int32(rl2PixelPtr ptr,int * sample)2292 rl2_get_pixel_sample_int32 (rl2PixelPtr ptr, int *sample)
2293 {
2294 /* get a Pixel/Sample value - INT32 */
2295 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2296 if (pxl == NULL)
2297 return RL2_ERROR;
2298 if (pxl->sampleType != RL2_SAMPLE_INT32)
2299 return RL2_ERROR;
2300 *sample = pxl->Samples->int32;
2301 return RL2_OK;
2302 }
2303
2304 RL2_DECLARE int
rl2_set_pixel_sample_int32(rl2PixelPtr ptr,int sample)2305 rl2_set_pixel_sample_int32 (rl2PixelPtr ptr, int sample)
2306 {
2307 /* set a Pixel/Sample value - INT32 */
2308 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2309 if (pxl == NULL)
2310 return RL2_ERROR;
2311 if (pxl->sampleType != RL2_SAMPLE_INT32)
2312 return RL2_ERROR;
2313 pxl->Samples->int32 = sample;
2314 return RL2_OK;
2315 }
2316
2317 RL2_DECLARE int
rl2_get_pixel_sample_uint32(rl2PixelPtr ptr,unsigned int * sample)2318 rl2_get_pixel_sample_uint32 (rl2PixelPtr ptr, unsigned int *sample)
2319 {
2320 /* get a Pixel/Sample value - UINT32 */
2321 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2322 if (pxl == NULL)
2323 return RL2_ERROR;
2324 if (pxl->sampleType != RL2_SAMPLE_UINT32)
2325 return RL2_ERROR;
2326 *sample = pxl->Samples->uint32;
2327 return RL2_OK;
2328 }
2329
2330 RL2_DECLARE int
rl2_set_pixel_sample_uint32(rl2PixelPtr ptr,unsigned int sample)2331 rl2_set_pixel_sample_uint32 (rl2PixelPtr ptr, unsigned int sample)
2332 {
2333 /* set a Pixel/Sample value - UINT32 */
2334 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2335 if (pxl == NULL)
2336 return RL2_ERROR;
2337 if (pxl->sampleType != RL2_SAMPLE_UINT32)
2338 return RL2_ERROR;
2339 pxl->Samples->uint32 = sample;
2340 return RL2_OK;
2341 }
2342
2343 RL2_DECLARE int
rl2_get_pixel_sample_float(rl2PixelPtr ptr,float * sample)2344 rl2_get_pixel_sample_float (rl2PixelPtr ptr, float *sample)
2345 {
2346 /* get a Pixel/Sample value - FLOAT */
2347 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2348 if (pxl == NULL)
2349 return RL2_ERROR;
2350 if (pxl->sampleType != RL2_SAMPLE_FLOAT)
2351 return RL2_ERROR;
2352 *sample = pxl->Samples->float32;
2353 return RL2_OK;
2354 }
2355
2356 RL2_DECLARE int
rl2_set_pixel_sample_float(rl2PixelPtr ptr,float sample)2357 rl2_set_pixel_sample_float (rl2PixelPtr ptr, float sample)
2358 {
2359 /* set a Pixel/Sample value - FLOAT */
2360 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2361 if (pxl == NULL)
2362 return RL2_ERROR;
2363 if (pxl->sampleType != RL2_SAMPLE_FLOAT)
2364 return RL2_ERROR;
2365 pxl->Samples->float32 = sample;
2366 return RL2_OK;
2367 }
2368
2369 RL2_DECLARE int
rl2_get_pixel_sample_double(rl2PixelPtr ptr,double * sample)2370 rl2_get_pixel_sample_double (rl2PixelPtr ptr, double *sample)
2371 {
2372 /* get a Pixel/Sample value - DOUBLE */
2373 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2374 if (pxl == NULL)
2375 return RL2_ERROR;
2376 if (pxl->sampleType != RL2_SAMPLE_DOUBLE)
2377 return RL2_ERROR;
2378 *sample = pxl->Samples->float64;
2379 return RL2_OK;
2380 }
2381
2382 RL2_DECLARE int
rl2_set_pixel_sample_double(rl2PixelPtr ptr,double sample)2383 rl2_set_pixel_sample_double (rl2PixelPtr ptr, double sample)
2384 {
2385 /* set a Pixel/Sample value - DOUBLE */
2386 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2387 if (pxl == NULL)
2388 return RL2_ERROR;
2389 if (pxl->sampleType != RL2_SAMPLE_DOUBLE)
2390 return RL2_ERROR;
2391 pxl->Samples->float64 = sample;
2392 return RL2_OK;
2393 }
2394
2395 RL2_DECLARE int
rl2_is_pixel_transparent(rl2PixelPtr ptr,int * is_transparent)2396 rl2_is_pixel_transparent (rl2PixelPtr ptr, int *is_transparent)
2397 {
2398 /* tests for a transparent pixel */
2399 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2400 if (pxl == NULL)
2401 return RL2_ERROR;
2402 if (pxl->isTransparent)
2403 *is_transparent = RL2_TRUE;
2404 else
2405 *is_transparent = RL2_FALSE;
2406 return RL2_OK;
2407 }
2408
2409 RL2_DECLARE int
rl2_is_pixel_opaque(rl2PixelPtr ptr,int * is_opaque)2410 rl2_is_pixel_opaque (rl2PixelPtr ptr, int *is_opaque)
2411 {
2412 /* tests for an opaque pixel */
2413 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2414 if (pxl == NULL)
2415 return RL2_ERROR;
2416 if (pxl->isTransparent)
2417 *is_opaque = RL2_FALSE;
2418 else
2419 *is_opaque = RL2_TRUE;
2420 return RL2_OK;
2421 }
2422
2423 RL2_DECLARE int
rl2_set_pixel_transparent(rl2PixelPtr ptr)2424 rl2_set_pixel_transparent (rl2PixelPtr ptr)
2425 {
2426 /* marks a pixel as transparent */
2427 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2428 if (pxl == NULL)
2429 return RL2_ERROR;
2430 pxl->isTransparent = 1;
2431 return RL2_OK;
2432 }
2433
2434 RL2_DECLARE int
rl2_set_pixel_opaque(rl2PixelPtr ptr)2435 rl2_set_pixel_opaque (rl2PixelPtr ptr)
2436 {
2437 /* marks a pixel as opaque */
2438 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) ptr;
2439 if (pxl == NULL)
2440 return RL2_ERROR;
2441 pxl->isTransparent = 0;
2442 return RL2_OK;
2443 }
2444
2445 RL2_DECLARE rl2PixelPtr
rl2_create_raster_pixel(rl2RasterPtr ptr)2446 rl2_create_raster_pixel (rl2RasterPtr ptr)
2447 {
2448 /* creating a Pixel matching the given Raster */
2449 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
2450 if (rst == NULL)
2451 return NULL;
2452 return rl2_create_pixel (rst->sampleType, rst->pixelType, rst->nBands);
2453 }
2454
2455 RL2_DECLARE int
rl2_get_raster_pixel(rl2RasterPtr ptr,rl2PixelPtr pixel,unsigned int row,unsigned int col)2456 rl2_get_raster_pixel (rl2RasterPtr ptr, rl2PixelPtr pixel, unsigned int row,
2457 unsigned int col)
2458 {
2459 /* fetching a Pixel from a Raster */
2460 int nBand;
2461 rl2PrivSamplePtr sample;
2462 char *p_int8;
2463 unsigned char *p_uint8;
2464 short *p_int16;
2465 unsigned short *p_uint16;
2466 int *p_int32;
2467 unsigned int *p_uint32;
2468 float *p_float32;
2469 double *p_float64;
2470 unsigned char *mask;
2471 unsigned char *p_mask;
2472 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
2473 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) pixel;
2474 if (rst == NULL)
2475 return RL2_ERROR;
2476 if (pxl == NULL)
2477 return RL2_ERROR;
2478
2479 if (pxl->sampleType != rst->sampleType || pxl->pixelType != rst->pixelType
2480 || pxl->nBands != rst->nBands)
2481 return RL2_ERROR;
2482 if (row >= rst->height || col >= rst->width)
2483 return RL2_ERROR;
2484
2485 for (nBand = 0; nBand < pxl->nBands; nBand++)
2486 {
2487 sample = pxl->Samples + nBand;
2488 switch (pxl->sampleType)
2489 {
2490 case RL2_SAMPLE_1_BIT:
2491 case RL2_SAMPLE_2_BIT:
2492 case RL2_SAMPLE_4_BIT:
2493 case RL2_SAMPLE_UINT8:
2494 p_uint8 = rst->rasterBuffer;
2495 p_uint8 +=
2496 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2497 nBand;
2498 sample->uint8 = *p_uint8;
2499 break;
2500 case RL2_SAMPLE_INT8:
2501 p_int8 = (char *) (rst->rasterBuffer);
2502 p_int8 +=
2503 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2504 nBand;
2505 sample->int8 = *p_int8;
2506 break;
2507 case RL2_SAMPLE_INT16:
2508 p_int16 = (short *) (rst->rasterBuffer);
2509 p_int16 +=
2510 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2511 nBand;
2512 sample->int16 = *p_int16;
2513 break;
2514 case RL2_SAMPLE_UINT16:
2515 p_uint16 = (unsigned short *) (rst->rasterBuffer);
2516 p_uint16 +=
2517 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2518 nBand;
2519 sample->uint16 = *p_uint16;
2520 break;
2521 case RL2_SAMPLE_INT32:
2522 p_int32 = (int *) (rst->rasterBuffer);
2523 p_int32 +=
2524 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2525 nBand;
2526 sample->int32 = *p_int32;
2527 break;
2528 case RL2_SAMPLE_UINT32:
2529 p_uint32 = (unsigned int *) (rst->rasterBuffer);
2530 p_uint32 +=
2531 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2532 nBand;
2533 sample->uint32 = *p_uint32;
2534 break;
2535 case RL2_SAMPLE_FLOAT:
2536 p_float32 = (float *) (rst->rasterBuffer);
2537 p_float32 +=
2538 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2539 nBand;
2540 sample->float32 = *p_float32;
2541 break;
2542 case RL2_SAMPLE_DOUBLE:
2543 p_float64 = (double *) (rst->rasterBuffer);
2544 p_float64 +=
2545 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2546 nBand;
2547 sample->float64 = *p_float64;
2548 break;
2549 };
2550 }
2551
2552 /* transparency */
2553 pxl->isTransparent = 0;
2554 mask = rst->maskBuffer;
2555 if (mask != NULL)
2556 {
2557 /* evaluating transparency mask */
2558 p_mask = mask + (row * rst->width) + col;
2559 if (*p_mask == 0)
2560 pxl->isTransparent = 1;
2561 }
2562 if (rst->noData != NULL)
2563 {
2564 /* evaluating transparent color */
2565 if (rl2_compare_pixels (pixel, (rl2PixelPtr) (rst->noData)) ==
2566 RL2_TRUE)
2567 pxl->isTransparent = 1;
2568 }
2569 return RL2_OK;
2570 }
2571
2572 RL2_DECLARE int
rl2_set_raster_pixel(rl2RasterPtr ptr,rl2PixelPtr pixel,unsigned int row,unsigned int col)2573 rl2_set_raster_pixel (rl2RasterPtr ptr, rl2PixelPtr pixel, unsigned int row,
2574 unsigned int col)
2575 {
2576 /* changing a Pixel into a Raster */
2577 int nBand;
2578 rl2PrivSamplePtr sample;
2579 char *p_int8;
2580 unsigned char *p_uint8;
2581 short *p_int16;
2582 unsigned short *p_uint16;
2583 int *p_int32;
2584 unsigned int *p_uint32;
2585 float *p_float32;
2586 double *p_float64;
2587 unsigned char *mask;
2588 unsigned char *p_mask;
2589 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
2590 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) pixel;
2591 if (rst == NULL)
2592 return RL2_ERROR;
2593 if (pxl == NULL)
2594 return RL2_ERROR;
2595
2596 if (pxl->sampleType != rst->sampleType || pxl->pixelType != rst->pixelType
2597 || pxl->nBands != rst->nBands)
2598 return RL2_ERROR;
2599 if (row >= rst->height || col >= rst->width)
2600 return RL2_ERROR;
2601 if (pxl->pixelType == RL2_PIXEL_PALETTE)
2602 {
2603 /* blocking any attempt to insert out-palette values */
2604 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) rst->Palette;
2605 if (pxl->Samples->uint8 >= plt->nEntries)
2606 return RL2_ERROR;
2607 }
2608
2609 for (nBand = 0; nBand < pxl->nBands; nBand++)
2610 {
2611 sample = pxl->Samples + nBand;
2612 switch (pxl->sampleType)
2613 {
2614 case RL2_SAMPLE_1_BIT:
2615 case RL2_SAMPLE_2_BIT:
2616 case RL2_SAMPLE_4_BIT:
2617 case RL2_SAMPLE_UINT8:
2618 p_uint8 = rst->rasterBuffer;
2619 p_uint8 +=
2620 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2621 nBand;
2622 *p_uint8 = sample->uint8;
2623 break;
2624 case RL2_SAMPLE_INT8:
2625 p_int8 = (char *) (rst->rasterBuffer);
2626 p_int8 +=
2627 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2628 nBand;
2629 *p_int8 = sample->int8;
2630 break;
2631 case RL2_SAMPLE_INT16:
2632 p_int16 = (short *) (rst->rasterBuffer);
2633 p_int16 +=
2634 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2635 nBand;
2636 *p_int16 = sample->int16;
2637 break;
2638 case RL2_SAMPLE_UINT16:
2639 p_uint16 = (unsigned short *) (rst->rasterBuffer);
2640 p_uint16 +=
2641 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2642 nBand;
2643 *p_uint16 = sample->uint16;
2644 break;
2645 case RL2_SAMPLE_INT32:
2646 p_int32 = (int *) (rst->rasterBuffer);
2647 p_int32 +=
2648 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2649 nBand;
2650 *p_int32 = sample->int32;
2651 break;
2652 case RL2_SAMPLE_UINT32:
2653 p_uint32 = (unsigned int *) (rst->rasterBuffer);
2654 p_uint32 +=
2655 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2656 nBand;
2657 *p_uint32 = sample->uint32;
2658 break;
2659 case RL2_SAMPLE_FLOAT:
2660 p_float32 = (float *) (rst->rasterBuffer);
2661 p_float32 +=
2662 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2663 nBand;
2664 *p_float32 = sample->float32;
2665 break;
2666 case RL2_SAMPLE_DOUBLE:
2667 p_float64 = (double *) (rst->rasterBuffer);
2668 p_float64 +=
2669 (row * rst->width * pxl->nBands) + (col * pxl->nBands) +
2670 nBand;
2671 *p_float64 = sample->float64;
2672 break;
2673 };
2674 }
2675
2676 mask = rst->maskBuffer;
2677 if (mask != NULL)
2678 {
2679 /* updating the transparency mask */
2680 p_mask = mask + (row * rst->width) + col;
2681 if (pxl->isTransparent)
2682 *p_mask = 0;
2683 else
2684 *p_mask = 1;
2685 }
2686 return RL2_OK;
2687 }
2688
2689 RL2_DECLARE rl2RasterStatisticsPtr
rl2_create_raster_statistics(unsigned char sample_type,unsigned char num_bands)2690 rl2_create_raster_statistics (unsigned char sample_type,
2691 unsigned char num_bands)
2692 {
2693 /* allocating and initializing a Raster Statistics object */
2694 int i;
2695 int j;
2696 int nHistogram;
2697 rl2PrivRasterStatisticsPtr stats = NULL;
2698 if (num_bands == 0)
2699 return NULL;
2700 switch (sample_type)
2701 {
2702 case RL2_SAMPLE_1_BIT:
2703 nHistogram = 2;
2704 break;
2705 case RL2_SAMPLE_2_BIT:
2706 nHistogram = 4;
2707 break;
2708 case RL2_SAMPLE_4_BIT:
2709 nHistogram = 16;
2710 break;
2711 default:
2712 nHistogram = 256;
2713 break;
2714 };
2715
2716 stats = malloc (sizeof (rl2PrivRasterStatistics));
2717 if (stats == NULL)
2718 return NULL;
2719 stats->no_data = 0.0;
2720 stats->count = 0.0;
2721 stats->sampleType = sample_type;
2722 stats->nBands = num_bands;
2723 stats->band_stats = malloc (sizeof (rl2PrivBandStatistics) * num_bands);
2724 if (stats->band_stats == NULL)
2725 {
2726 free (stats);
2727 return NULL;
2728 }
2729 for (i = 0; i < num_bands; i++)
2730 {
2731 /* initializing the Bands Statistics */
2732 rl2PrivBandStatisticsPtr band = stats->band_stats + i;
2733 band->min = DBL_MAX;
2734 band->max = 0.0 - DBL_MAX;
2735 band->mean = 0.0;
2736 band->sum_sq_diff = 0.0;
2737 band->nHistogram = nHistogram;
2738 band->histogram = malloc (sizeof (double) * nHistogram);
2739 for (j = 0; j < nHistogram; j++)
2740 *(band->histogram + j) = 0.0;
2741 band->first = NULL;
2742 band->last = NULL;
2743 }
2744 return (rl2RasterStatisticsPtr) stats;
2745 }
2746
2747 static void
free_band_stats(rl2PrivBandStatisticsPtr band)2748 free_band_stats (rl2PrivBandStatisticsPtr band)
2749 {
2750 /* memory cleanup - destroying a Raster Band Statistics object */
2751 rl2PoolVariancePtr pV;
2752 rl2PoolVariancePtr pVn;
2753 if (band == NULL)
2754 return;
2755 if (band->histogram != NULL)
2756 free (band->histogram);
2757 pV = band->first;
2758 while (pV != NULL)
2759 {
2760 pVn = pV->next;
2761 free (pV);
2762 pV = pVn;
2763 }
2764 }
2765
2766 RL2_DECLARE void
rl2_destroy_raster_statistics(rl2RasterStatisticsPtr stats)2767 rl2_destroy_raster_statistics (rl2RasterStatisticsPtr stats)
2768 {
2769 /* memory cleanup - destroying a Raster Statistics object */
2770 int nb;
2771 rl2PrivRasterStatisticsPtr st = (rl2PrivRasterStatisticsPtr) stats;
2772 if (st == NULL)
2773 return;
2774 for (nb = 0; nb < st->nBands; nb++)
2775 {
2776 rl2PrivBandStatisticsPtr band = st->band_stats + nb;
2777 free_band_stats (band);
2778 }
2779 if (st->band_stats != NULL)
2780 free (st->band_stats);
2781 free (st);
2782 }
2783
2784 RL2_DECLARE int
rl2_get_raster_statistics_summary(rl2RasterStatisticsPtr stats,double * no_data,double * count,unsigned char * sample_type,unsigned char * num_bands)2785 rl2_get_raster_statistics_summary (rl2RasterStatisticsPtr stats,
2786 double *no_data, double *count,
2787 unsigned char *sample_type,
2788 unsigned char *num_bands)
2789 {
2790 /* returning overall statistics values */
2791 rl2PrivRasterStatisticsPtr st = (rl2PrivRasterStatisticsPtr) stats;
2792 if (st == NULL)
2793 return RL2_ERROR;
2794 *no_data = st->no_data;
2795 *count = st->count;
2796 *sample_type = st->sampleType;
2797 *num_bands = st->nBands;
2798 return RL2_OK;
2799 }
2800
2801 RL2_DECLARE int
rl2_get_band_statistics(rl2RasterStatisticsPtr stats,unsigned char band,double * min,double * max,double * mean,double * variance,double * standard_deviation)2802 rl2_get_band_statistics (rl2RasterStatisticsPtr stats, unsigned char band,
2803 double *min, double *max, double *mean,
2804 double *variance, double *standard_deviation)
2805 {
2806 /* returning Band statistics values */
2807 rl2PrivBandStatisticsPtr st_band;
2808 rl2PrivRasterStatisticsPtr st = (rl2PrivRasterStatisticsPtr) stats;
2809 if (st == NULL)
2810 return RL2_ERROR;
2811 if (band >= st->nBands)
2812 return RL2_ERROR;
2813
2814 st_band = st->band_stats + band;
2815 *min = st_band->min;
2816 *max = st_band->max;
2817 *mean = st_band->mean;
2818 if (st_band->first != NULL)
2819 {
2820 double count = 0.0;
2821 double sum_var = 0.0;
2822 double sum_count = 0.0;
2823 rl2PoolVariancePtr pV = st_band->first;
2824 while (pV != NULL)
2825 {
2826 count += 1.0;
2827 sum_var += (pV->count - 1.0) * pV->variance;
2828 sum_count += pV->count;
2829 pV = pV->next;
2830 }
2831 *variance = sum_var / (sum_count - count);
2832 }
2833 else
2834 *variance = st_band->sum_sq_diff / (st->count - 1.0);
2835 *standard_deviation = sqrt (*variance);
2836 return RL2_OK;
2837 }
2838