1 /*
2
3 rl2codec -- encoding/decoding functions
4
5 version 0.1, 2013 April 1
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 <zlib.h>
50 #include <lzma.h>
51
52 #include "config.h"
53
54 #ifdef LOADABLE_EXTENSION
55 #include "rasterlite2/sqlite.h"
56 #endif
57
58 #include "rasterlite2/rasterlite2.h"
59 #include "rasterlite2/rl2tiff.h"
60 #include "rasterlite2_private.h"
61
62 static int
endianArch()63 endianArch ()
64 {
65 /* checking if target CPU is a little-endian one */
66 union cvt
67 {
68 unsigned char byte[4];
69 int int_value;
70 } convert;
71 convert.int_value = 1;
72 if (convert.byte[0] == 0)
73 return 0;
74 return 1;
75 }
76
77 static void
exportU16(unsigned char * p,unsigned short value,int little_endian,int little_endian_arch)78 exportU16 (unsigned char *p, unsigned short value, int little_endian,
79 int little_endian_arch)
80 {
81 /* stores a 16bit int into a BLOB respecting declared endiannes */
82 union cvt
83 {
84 unsigned char byte[2];
85 unsigned short int_value;
86 } convert;
87 convert.int_value = value;
88 if (little_endian_arch)
89 {
90 /* Litte-Endian architecture [e.g. x86] */
91 if (!little_endian)
92 {
93 /* Big Endian data */
94 *(p + 1) = convert.byte[0];
95 *(p + 0) = convert.byte[1];
96 }
97 else
98 {
99 /* Little Endian data */
100 *(p + 0) = convert.byte[0];
101 *(p + 1) = convert.byte[1];
102 }
103 }
104 else
105 {
106 /* Big Endian architecture [e.g. PPC] */
107 if (!little_endian)
108 {
109 /* Big Endian data */
110 *(p + 0) = convert.byte[0];
111 *(p + 1) = convert.byte[1];
112 }
113 else
114 {
115 /* Little Endian data */
116 *(p + 1) = convert.byte[0];
117 *(p + 0) = convert.byte[1];
118 }
119 }
120 }
121
122 static short
import16(const unsigned char * p,int little_endian,int little_endian_arch)123 import16 (const unsigned char *p, int little_endian, int little_endian_arch)
124 {
125 /* fetches a 16bit int from BLOB respecting declared endiannes */
126 union cvt
127 {
128 unsigned char byte[2];
129 short int_value;
130 } convert;
131 if (little_endian_arch)
132 {
133 /* Litte-Endian architecture [e.g. x86] */
134 if (!little_endian)
135 {
136 /* Big Endian data */
137 convert.byte[0] = *(p + 1);
138 convert.byte[1] = *(p + 0);
139 }
140 else
141 {
142 /* Little Endian data */
143 convert.byte[0] = *(p + 0);
144 convert.byte[1] = *(p + 1);
145 }
146 }
147 else
148 {
149 /* Big Endian architecture [e.g. PPC] */
150 if (!little_endian)
151 {
152 /* Big Endian data */
153 convert.byte[0] = *(p + 0);
154 convert.byte[1] = *(p + 1);
155 }
156 else
157 {
158 /* Little Endian data */
159 convert.byte[0] = *(p + 1);
160 convert.byte[1] = *(p + 0);
161 }
162 }
163 return convert.int_value;
164 }
165
166 static void
export16(unsigned char * p,short value,int little_endian,int little_endian_arch)167 export16 (unsigned char *p, short value, int little_endian,
168 int little_endian_arch)
169 {
170 /* stores a 16bit int into a BLOB respecting declared endiannes */
171 union cvt
172 {
173 unsigned char byte[2];
174 short int_value;
175 } convert;
176 convert.int_value = value;
177 if (little_endian_arch)
178 {
179 /* Litte-Endian architecture [e.g. x86] */
180 if (!little_endian)
181 {
182 /* Big Endian data */
183 *(p + 1) = convert.byte[0];
184 *(p + 0) = convert.byte[1];
185 }
186 else
187 {
188 /* Little Endian data */
189 *(p + 0) = convert.byte[0];
190 *(p + 1) = convert.byte[1];
191 }
192 }
193 else
194 {
195 /* Big Endian architecture [e.g. PPC] */
196 if (!little_endian)
197 {
198 /* Big Endian data */
199 *(p + 0) = convert.byte[0];
200 *(p + 1) = convert.byte[1];
201 }
202 else
203 {
204 /* Little Endian data */
205 *(p + 1) = convert.byte[0];
206 *(p + 0) = convert.byte[1];
207 }
208 }
209 }
210
211 static unsigned short
importU16(const unsigned char * p,int little_endian,int little_endian_arch)212 importU16 (const unsigned char *p, int little_endian, int little_endian_arch)
213 {
214 /* fetches a 16bit uint from BLOB respecting declared endiannes */
215 union cvt
216 {
217 unsigned char byte[2];
218 unsigned short int_value;
219 } convert;
220 if (little_endian_arch)
221 {
222 /* Litte-Endian architecture [e.g. x86] */
223 if (!little_endian)
224 {
225 /* Big Endian data */
226 convert.byte[0] = *(p + 1);
227 convert.byte[1] = *(p + 0);
228 }
229 else
230 {
231 /* Little Endian data */
232 convert.byte[0] = *(p + 0);
233 convert.byte[1] = *(p + 1);
234 }
235 }
236 else
237 {
238 /* Big Endian architecture [e.g. PPC] */
239 if (!little_endian)
240 {
241 /* Big Endian data */
242 convert.byte[0] = *(p + 0);
243 convert.byte[1] = *(p + 1);
244 }
245 else
246 {
247 /* Little Endian data */
248 convert.byte[0] = *(p + 1);
249 convert.byte[1] = *(p + 0);
250 }
251 }
252 return convert.int_value;
253 }
254
255 static void
exportU32(unsigned char * p,unsigned int value,int little_endian,int little_endian_arch)256 exportU32 (unsigned char *p, unsigned int value, int little_endian,
257 int little_endian_arch)
258 {
259 /* stores a 32bit int into a BLOB respecting declared endiannes */
260 union cvt
261 {
262 unsigned char byte[4];
263 unsigned int int_value;
264 } convert;
265 convert.int_value = value;
266 if (little_endian_arch)
267 {
268 /* Litte-Endian architecture [e.g. x86] */
269 if (!little_endian)
270 {
271 /* Big Endian data */
272 *(p + 3) = convert.byte[0];
273 *(p + 2) = convert.byte[1];
274 *(p + 1) = convert.byte[2];
275 *(p + 0) = convert.byte[3];
276 }
277 else
278 {
279 /* Little Endian data */
280 *(p + 0) = convert.byte[0];
281 *(p + 1) = convert.byte[1];
282 *(p + 2) = convert.byte[2];
283 *(p + 3) = convert.byte[3];
284 }
285 }
286 else
287 {
288 /* Big Endian architecture [e.g. PPC] */
289 if (!little_endian)
290 {
291 /* Big Endian data */
292 *(p + 0) = convert.byte[0];
293 *(p + 1) = convert.byte[1];
294 *(p + 2) = convert.byte[2];
295 *(p + 3) = convert.byte[3];
296 }
297 else
298 {
299 /* Little Endian data */
300 *(p + 3) = convert.byte[0];
301 *(p + 2) = convert.byte[1];
302 *(p + 1) = convert.byte[2];
303 *(p + 0) = convert.byte[3];
304 }
305 }
306 }
307
308 static unsigned int
importU32(const unsigned char * p,int little_endian,int little_endian_arch)309 importU32 (const unsigned char *p, int little_endian, int little_endian_arch)
310 {
311 /* fetches a 32bit uint from BLOB respecting declared endiannes */
312 union cvt
313 {
314 unsigned char byte[4];
315 unsigned int int_value;
316 } convert;
317 if (little_endian_arch)
318 {
319 /* Litte-Endian architecture [e.g. x86] */
320 if (!little_endian)
321 {
322 /* Big Endian data */
323 convert.byte[0] = *(p + 3);
324 convert.byte[1] = *(p + 2);
325 convert.byte[2] = *(p + 1);
326 convert.byte[3] = *(p + 0);
327 }
328 else
329 {
330 /* Little Endian data */
331 convert.byte[0] = *(p + 0);
332 convert.byte[1] = *(p + 1);
333 convert.byte[2] = *(p + 2);
334 convert.byte[3] = *(p + 3);
335 }
336 }
337 else
338 {
339 /* Big Endian architecture [e.g. PPC] */
340 if (!little_endian)
341 {
342 /* Big Endian data */
343 convert.byte[0] = *(p + 0);
344 convert.byte[1] = *(p + 1);
345 convert.byte[2] = *(p + 2);
346 convert.byte[3] = *(p + 3);
347 }
348 else
349 {
350 /* Little Endian data */
351 convert.byte[0] = *(p + 3);
352 convert.byte[1] = *(p + 2);
353 convert.byte[2] = *(p + 1);
354 convert.byte[3] = *(p + 0);
355 }
356 }
357 return convert.int_value;
358 }
359
360 static void
export32(unsigned char * p,int value,int little_endian,int little_endian_arch)361 export32 (unsigned char *p, int value, int little_endian,
362 int little_endian_arch)
363 {
364 /* stores a 32bit int into a BLOB respecting declared endiannes */
365 union cvt
366 {
367 unsigned char byte[4];
368 int int_value;
369 } convert;
370 convert.int_value = value;
371 if (little_endian_arch)
372 {
373 /* Litte-Endian architecture [e.g. x86] */
374 if (!little_endian)
375 {
376 /* Big Endian data */
377 *(p + 3) = convert.byte[0];
378 *(p + 2) = convert.byte[1];
379 *(p + 1) = convert.byte[2];
380 *(p + 0) = convert.byte[3];
381 }
382 else
383 {
384 /* Little Endian data */
385 *(p + 0) = convert.byte[0];
386 *(p + 1) = convert.byte[1];
387 *(p + 2) = convert.byte[2];
388 *(p + 3) = convert.byte[3];
389 }
390 }
391 else
392 {
393 /* Big Endian architecture [e.g. PPC] */
394 if (!little_endian)
395 {
396 /* Big Endian data */
397 *(p + 0) = convert.byte[0];
398 *(p + 1) = convert.byte[1];
399 *(p + 2) = convert.byte[2];
400 *(p + 3) = convert.byte[3];
401 }
402 else
403 {
404 /* Little Endian data */
405 *(p + 3) = convert.byte[0];
406 *(p + 2) = convert.byte[1];
407 *(p + 1) = convert.byte[2];
408 *(p + 0) = convert.byte[3];
409 }
410 }
411 }
412
413 static int
import32(const unsigned char * p,int little_endian,int little_endian_arch)414 import32 (const unsigned char *p, int little_endian, int little_endian_arch)
415 {
416 /* fetches a 32bit int from BLOB respecting declared endiannes */
417 union cvt
418 {
419 unsigned char byte[4];
420 int int_value;
421 } convert;
422 if (little_endian_arch)
423 {
424 /* Litte-Endian architecture [e.g. x86] */
425 if (!little_endian)
426 {
427 /* Big Endian data */
428 convert.byte[0] = *(p + 3);
429 convert.byte[1] = *(p + 2);
430 convert.byte[2] = *(p + 1);
431 convert.byte[3] = *(p + 0);
432 }
433 else
434 {
435 /* Little Endian data */
436 convert.byte[0] = *(p + 0);
437 convert.byte[1] = *(p + 1);
438 convert.byte[2] = *(p + 2);
439 convert.byte[3] = *(p + 3);
440 }
441 }
442 else
443 {
444 /* Big Endian architecture [e.g. PPC] */
445 if (!little_endian)
446 {
447 /* Big Endian data */
448 convert.byte[0] = *(p + 0);
449 convert.byte[1] = *(p + 1);
450 convert.byte[2] = *(p + 2);
451 convert.byte[3] = *(p + 3);
452 }
453 else
454 {
455 /* Little Endian data */
456 convert.byte[0] = *(p + 3);
457 convert.byte[1] = *(p + 2);
458 convert.byte[2] = *(p + 1);
459 convert.byte[3] = *(p + 0);
460 }
461 }
462 return convert.int_value;
463 }
464
465 static void
exportFloat(unsigned char * p,float value,int little_endian,int little_endian_arch)466 exportFloat (unsigned char *p, float value, int little_endian,
467 int little_endian_arch)
468 {
469 /* stores a 32bit Float into a BLOB respecting declared endiannes */
470 union cvt
471 {
472 unsigned char byte[4];
473 float flt_value;
474 } convert;
475 convert.flt_value = value;
476 if (little_endian_arch)
477 {
478 /* Litte-Endian architecture [e.g. x86] */
479 if (!little_endian)
480 {
481 /* Big Endian data */
482 *(p + 3) = convert.byte[0];
483 *(p + 2) = convert.byte[1];
484 *(p + 1) = convert.byte[2];
485 *(p + 0) = convert.byte[3];
486 }
487 else
488 {
489 /* Little Endian data */
490 *(p + 0) = convert.byte[0];
491 *(p + 1) = convert.byte[1];
492 *(p + 2) = convert.byte[2];
493 *(p + 3) = convert.byte[3];
494 }
495 }
496 else
497 {
498 /* Big Endian architecture [e.g. PPC] */
499 if (!little_endian)
500 {
501 /* Big Endian data */
502 *(p + 0) = convert.byte[0];
503 *(p + 1) = convert.byte[1];
504 *(p + 2) = convert.byte[2];
505 *(p + 3) = convert.byte[3];
506 }
507 else
508 {
509 /* Little Endian data */
510 *(p + 3) = convert.byte[0];
511 *(p + 2) = convert.byte[1];
512 *(p + 1) = convert.byte[2];
513 *(p + 0) = convert.byte[3];
514 }
515 }
516 }
517
518 static float
importFloat(const unsigned char * p,int little_endian,int little_endian_arch)519 importFloat (const unsigned char *p, int little_endian, int little_endian_arch)
520 {
521 /* fetches a 32bit Float from BLOB respecting declared endiannes */
522 union cvt
523 {
524 unsigned char byte[4];
525 float flt_value;
526 } convert;
527 if (little_endian_arch)
528 {
529 /* Litte-Endian architecture [e.g. x86] */
530 if (!little_endian)
531 {
532 /* Big Endian data */
533 convert.byte[0] = *(p + 3);
534 convert.byte[1] = *(p + 2);
535 convert.byte[2] = *(p + 1);
536 convert.byte[3] = *(p + 0);
537 }
538 else
539 {
540 /* Little Endian data */
541 convert.byte[0] = *(p + 0);
542 convert.byte[1] = *(p + 1);
543 convert.byte[2] = *(p + 2);
544 convert.byte[3] = *(p + 3);
545 }
546 }
547 else
548 {
549 /* Big Endian architecture [e.g. PPC] */
550 if (!little_endian)
551 {
552 /* Big Endian data */
553 convert.byte[0] = *(p + 0);
554 convert.byte[1] = *(p + 1);
555 convert.byte[2] = *(p + 2);
556 convert.byte[3] = *(p + 3);
557 }
558 else
559 {
560 /* Little Endian data */
561 convert.byte[0] = *(p + 3);
562 convert.byte[1] = *(p + 2);
563 convert.byte[2] = *(p + 1);
564 convert.byte[3] = *(p + 0);
565 }
566 }
567 return convert.flt_value;
568 }
569
570 static void
exportDouble(unsigned char * p,double value,int little_endian,int little_endian_arch)571 exportDouble (unsigned char *p, double value, int little_endian,
572 int little_endian_arch)
573 {
574 /* stores a Double into a BLOB respecting declared endiannes */
575 union cvt
576 {
577 unsigned char byte[8];
578 double dbl_value;
579 } convert;
580 convert.dbl_value = value;
581 if (little_endian_arch)
582 {
583 /* Litte-Endian architecture [e.g. x86] */
584 if (!little_endian)
585 {
586 /* Big Endian data */
587 *(p + 7) = convert.byte[0];
588 *(p + 6) = convert.byte[1];
589 *(p + 5) = convert.byte[2];
590 *(p + 4) = convert.byte[3];
591 *(p + 3) = convert.byte[4];
592 *(p + 2) = convert.byte[5];
593 *(p + 1) = convert.byte[6];
594 *(p + 0) = convert.byte[7];
595 }
596 else
597 {
598 /* Little Endian data */
599 *(p + 0) = convert.byte[0];
600 *(p + 1) = convert.byte[1];
601 *(p + 2) = convert.byte[2];
602 *(p + 3) = convert.byte[3];
603 *(p + 4) = convert.byte[4];
604 *(p + 5) = convert.byte[5];
605 *(p + 6) = convert.byte[6];
606 *(p + 7) = convert.byte[7];
607 }
608 }
609 else
610 {
611 /* Big Endian architecture [e.g. PPC] */
612 if (!little_endian)
613 {
614 /* Big Endian data */
615 *(p + 0) = convert.byte[0];
616 *(p + 1) = convert.byte[1];
617 *(p + 2) = convert.byte[2];
618 *(p + 3) = convert.byte[3];
619 *(p + 4) = convert.byte[4];
620 *(p + 5) = convert.byte[5];
621 *(p + 6) = convert.byte[6];
622 *(p + 7) = convert.byte[7];
623 }
624 else
625 {
626 /* Little Endian data */
627 *(p + 7) = convert.byte[0];
628 *(p + 6) = convert.byte[1];
629 *(p + 5) = convert.byte[2];
630 *(p + 4) = convert.byte[3];
631 *(p + 3) = convert.byte[4];
632 *(p + 2) = convert.byte[5];
633 *(p + 1) = convert.byte[6];
634 *(p + 0) = convert.byte[7];
635 }
636 }
637 }
638
639 static double
importDouble(const unsigned char * p,int little_endian,int little_endian_arch)640 importDouble (const unsigned char *p, int little_endian, int little_endian_arch)
641 {
642 /* fetches a Double from BLOB respecting declared endiannes */
643 union cvt
644 {
645 unsigned char byte[8];
646 double dbl_value;
647 } convert;
648 if (little_endian_arch)
649 {
650 /* Litte-Endian architecture [e.g. x86] */
651 if (!little_endian)
652 {
653 /* Big Endian data */
654 convert.byte[0] = *(p + 7);
655 convert.byte[1] = *(p + 6);
656 convert.byte[2] = *(p + 5);
657 convert.byte[3] = *(p + 4);
658 convert.byte[4] = *(p + 3);
659 convert.byte[5] = *(p + 2);
660 convert.byte[6] = *(p + 1);
661 convert.byte[7] = *(p + 0);
662 }
663 else
664 {
665 /* Little Endian data */
666 convert.byte[0] = *(p + 0);
667 convert.byte[1] = *(p + 1);
668 convert.byte[2] = *(p + 2);
669 convert.byte[3] = *(p + 3);
670 convert.byte[4] = *(p + 4);
671 convert.byte[5] = *(p + 5);
672 convert.byte[6] = *(p + 6);
673 convert.byte[7] = *(p + 7);
674 }
675 }
676 else
677 {
678 /* Big Endian architecture [e.g. PPC] */
679 if (!little_endian)
680 {
681 /* Big Endian data */
682 convert.byte[0] = *(p + 0);
683 convert.byte[1] = *(p + 1);
684 convert.byte[2] = *(p + 2);
685 convert.byte[3] = *(p + 3);
686 convert.byte[4] = *(p + 4);
687 convert.byte[5] = *(p + 5);
688 convert.byte[6] = *(p + 6);
689 convert.byte[7] = *(p + 7);
690 }
691 else
692 {
693 /* Little Endian data */
694 convert.byte[0] = *(p + 7);
695 convert.byte[1] = *(p + 6);
696 convert.byte[2] = *(p + 5);
697 convert.byte[3] = *(p + 4);
698 convert.byte[4] = *(p + 3);
699 convert.byte[5] = *(p + 2);
700 convert.byte[6] = *(p + 1);
701 convert.byte[7] = *(p + 0);
702 }
703 }
704 return convert.dbl_value;
705 }
706
707 static short
swapINT16(short value)708 swapINT16 (short value)
709 {
710 /* swaps a INT16 respecting declared endiannes */
711 union cvt
712 {
713 unsigned char byte[4];
714 short value;
715 } convert1;
716 union cvt convert2;
717 convert1.value = value;
718 convert2.byte[0] = convert1.byte[1];
719 convert2.byte[1] = convert1.byte[0];
720 return convert2.value;
721 }
722
723 static unsigned short
swapUINT16(unsigned short value)724 swapUINT16 (unsigned short value)
725 {
726 /* swaps a UINT16 respecting declared endiannes */
727 union cvt
728 {
729 unsigned char byte[4];
730 unsigned short value;
731 } convert1;
732 union cvt convert2;
733 convert1.value = value;
734 convert2.byte[0] = convert1.byte[1];
735 convert2.byte[1] = convert1.byte[0];
736 return convert2.value;
737 }
738
739 static int
swapINT32(int value)740 swapINT32 (int value)
741 {
742 /* swaps an INT32 respecting declared endiannes */
743 union cvt
744 {
745 unsigned char byte[4];
746 int value;
747 } convert1;
748 union cvt convert2;
749 convert1.value = value;
750 convert2.byte[0] = convert1.byte[3];
751 convert2.byte[1] = convert1.byte[2];
752 convert2.byte[2] = convert1.byte[1];
753 convert2.byte[3] = convert1.byte[0];
754 return convert2.value;
755 }
756
757 static unsigned int
swapUINT32(unsigned int value)758 swapUINT32 (unsigned int value)
759 {
760 /* swaps a UINT32 respecting declared endiannes */
761 union cvt
762 {
763 unsigned char byte[4];
764 unsigned int value;
765 } convert1;
766 union cvt convert2;
767 convert1.value = value;
768 convert2.byte[0] = convert1.byte[3];
769 convert2.byte[1] = convert1.byte[2];
770 convert2.byte[2] = convert1.byte[1];
771 convert2.byte[3] = convert1.byte[0];
772 return convert2.value;
773 }
774
775 static float
swapFloat(float value)776 swapFloat (float value)
777 {
778 /* swaps a Float respecting declared endiannes */
779 union cvt
780 {
781 unsigned char byte[4];
782 float value;
783 } convert1;
784 union cvt convert2;
785 convert1.value = value;
786 convert2.byte[0] = convert1.byte[3];
787 convert2.byte[1] = convert1.byte[2];
788 convert2.byte[2] = convert1.byte[1];
789 convert2.byte[3] = convert1.byte[0];
790 return convert2.value;
791 }
792
793 static double
swapDouble(double value)794 swapDouble (double value)
795 {
796 /* swaps a Double respecting declared endiannes */
797 union cvt
798 {
799 unsigned char byte[8];
800 double value;
801 } convert1;
802 union cvt convert2;
803 convert1.value = value;
804 convert2.byte[0] = convert1.byte[7];
805 convert2.byte[1] = convert1.byte[6];
806 convert2.byte[2] = convert1.byte[5];
807 convert2.byte[3] = convert1.byte[4];
808 convert2.byte[4] = convert1.byte[3];
809 convert2.byte[5] = convert1.byte[2];
810 convert2.byte[6] = convert1.byte[1];
811 convert2.byte[7] = convert1.byte[0];
812 return convert2.value;
813 }
814
815 static int
check_encode_self_consistency(unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples,unsigned char compression)816 check_encode_self_consistency (unsigned char sample_type,
817 unsigned char pixel_type,
818 unsigned char num_samples,
819 unsigned char compression)
820 {
821 /* checking overall self-consistency for coverage params */
822 switch (pixel_type)
823 {
824 case RL2_PIXEL_MONOCHROME:
825 if (sample_type != RL2_SAMPLE_1_BIT || num_samples != 1)
826 return 0;
827 switch (compression)
828 {
829 case RL2_COMPRESSION_NONE:
830 case RL2_COMPRESSION_PNG:
831 case RL2_COMPRESSION_CCITTFAX4:
832 break;
833 default:
834 return 0;
835 };
836 break;
837 case RL2_PIXEL_PALETTE:
838 switch (sample_type)
839 {
840 case RL2_SAMPLE_1_BIT:
841 case RL2_SAMPLE_2_BIT:
842 case RL2_SAMPLE_4_BIT:
843 case RL2_SAMPLE_UINT8:
844 break;
845 default:
846 return 0;
847 };
848 if (num_samples != 1)
849 return 0;
850 switch (compression)
851 {
852 case RL2_COMPRESSION_NONE:
853 case RL2_COMPRESSION_PNG:
854 break;
855 default:
856 return 0;
857 };
858 break;
859 case RL2_PIXEL_GRAYSCALE:
860 switch (sample_type)
861 {
862 case RL2_SAMPLE_2_BIT:
863 case RL2_SAMPLE_4_BIT:
864 case RL2_SAMPLE_UINT8:
865 break;
866 default:
867 return 0;
868 };
869 if (num_samples != 1)
870 return 0;
871 switch (compression)
872 {
873 case RL2_COMPRESSION_NONE:
874 case RL2_COMPRESSION_PNG:
875 case RL2_COMPRESSION_JPEG:
876 case RL2_COMPRESSION_LOSSY_WEBP:
877 case RL2_COMPRESSION_LOSSLESS_WEBP:
878 break;
879 default:
880 return 0;
881 };
882 break;
883 case RL2_PIXEL_RGB:
884 switch (sample_type)
885 {
886 case RL2_SAMPLE_UINT8:
887 case RL2_SAMPLE_UINT16:
888 break;
889 default:
890 return 0;
891 };
892 if (num_samples != 3)
893 return 0;
894 if (sample_type == RL2_SAMPLE_UINT16)
895 {
896 switch (compression)
897 {
898 case RL2_COMPRESSION_NONE:
899 case RL2_COMPRESSION_DEFLATE:
900 case RL2_COMPRESSION_LZMA:
901 break;
902 default:
903 return 0;
904 };
905 }
906 else
907 {
908 switch (compression)
909 {
910 case RL2_COMPRESSION_NONE:
911 case RL2_COMPRESSION_PNG:
912 case RL2_COMPRESSION_JPEG:
913 case RL2_COMPRESSION_LOSSY_WEBP:
914 case RL2_COMPRESSION_LOSSLESS_WEBP:
915 break;
916 default:
917 return 0;
918 };
919 }
920 break;
921 case RL2_PIXEL_MULTIBAND:
922 switch (sample_type)
923 {
924 case RL2_SAMPLE_UINT8:
925 case RL2_SAMPLE_UINT16:
926 break;
927 default:
928 return 0;
929 };
930 if (num_samples < 2)
931 return 0;
932 switch (compression)
933 {
934 case RL2_COMPRESSION_NONE:
935 case RL2_COMPRESSION_DEFLATE:
936 case RL2_COMPRESSION_LZMA:
937 break;
938 default:
939 return 0;
940 };
941 break;
942 case RL2_PIXEL_DATAGRID:
943 switch (sample_type)
944 {
945 case RL2_SAMPLE_INT8:
946 case RL2_SAMPLE_UINT8:
947 case RL2_SAMPLE_INT16:
948 case RL2_SAMPLE_UINT16:
949 case RL2_SAMPLE_INT32:
950 case RL2_SAMPLE_UINT32:
951 case RL2_SAMPLE_FLOAT:
952 case RL2_SAMPLE_DOUBLE:
953 break;
954 default:
955 return 0;
956 };
957 if (num_samples != 1)
958 return 0;
959 switch (compression)
960 {
961 case RL2_COMPRESSION_NONE:
962 case RL2_COMPRESSION_DEFLATE:
963 case RL2_COMPRESSION_LZMA:
964 break;
965 default:
966 return 0;
967 };
968 break;
969 };
970 return 1;
971 }
972
973 static int
pack_rle_rows(rl2PrivRasterPtr raster,unsigned char * in,unsigned char ** pixels,int * size)974 pack_rle_rows (rl2PrivRasterPtr raster, unsigned char *in,
975 unsigned char **pixels, int *size)
976 {
977 /* creating an RLE encoded 1-BIT pixel buffer */
978 int sz = 0;
979 unsigned char *p_in = in;
980 unsigned char *rle;
981 unsigned char *p_out;
982 unsigned int row;
983 unsigned int col;
984
985 for (row = 0; row < raster->height; row++)
986 {
987 int cnt = 0;
988 int pix = *p_in;
989 for (col = 0; col < raster->width; col++)
990 {
991 /* computing the required size */
992 if (pix == *p_in)
993 {
994 if (cnt == 128)
995 {
996 sz++;
997 cnt = 1;
998 }
999 else
1000 cnt++;
1001 }
1002 else
1003 {
1004 sz++;
1005 pix = *p_in;
1006 cnt = 1;
1007 }
1008 p_in++;
1009 }
1010 sz++;
1011 }
1012
1013 rle = malloc (sz);
1014 p_out = rle;
1015 p_in = in;
1016 for (row = 0; row < raster->height; row++)
1017 {
1018 char byte;
1019 int cnt = 0;
1020 int pix = *p_in;
1021 for (col = 0; col < raster->width; col++)
1022 {
1023 /* RLE encoding */
1024 if (pix == *p_in)
1025 {
1026 if (cnt == 128)
1027 {
1028 if (pix == 1)
1029 {
1030 byte = 127;
1031 *p_out++ = byte;
1032 }
1033 else
1034 {
1035 byte = -128;
1036 *p_out++ = byte;
1037 }
1038 cnt = 1;
1039 }
1040 else
1041 cnt++;
1042 }
1043 else
1044 {
1045 if (pix == 1)
1046 {
1047 byte = cnt - 1;
1048 *p_out++ = byte;
1049 }
1050 else
1051 {
1052 byte = cnt * -1;
1053 *p_out++ = byte;
1054 }
1055 pix = *p_in;
1056 cnt = 1;
1057 }
1058 p_in++;
1059 }
1060 if (pix == 1)
1061 {
1062 byte = cnt - 1;
1063 *p_out++ = byte;
1064 }
1065 else
1066 {
1067 byte = cnt * -1;
1068 *p_out++ = byte;
1069 }
1070 }
1071 *pixels = rle;
1072 *size = sz;
1073 return 1;
1074 }
1075
1076 static int
unpack_rle(unsigned short width,unsigned short height,const unsigned char * pixels_in,int pixels_in_sz,unsigned char ** pixels,int * pixels_sz)1077 unpack_rle (unsigned short width, unsigned short height,
1078 const unsigned char *pixels_in, int pixels_in_sz,
1079 unsigned char **pixels, int *pixels_sz)
1080 {
1081 /* unpacking an RLE encoded 1-BIT raster */
1082 unsigned char *buf;
1083 int buf_size;
1084 int col;
1085 int byte;
1086 int i;
1087 unsigned char px;
1088 int row_stride;
1089 int row_no;
1090 int cnt;
1091 unsigned char *p_out;
1092 const char *p_in;
1093
1094 p_in = (char *) pixels_in;
1095 row_stride = 0;
1096 row_no = 0;
1097 for (col = 0; col < pixels_in_sz; col++)
1098 {
1099 /* checking the encoded buffer for validity */
1100 byte = *p_in++;
1101 if (byte < 0)
1102 row_stride += byte * -1;
1103 else
1104 row_stride += byte + 1;
1105 if (row_stride == width)
1106 {
1107 row_stride = 0;
1108 row_no++;
1109 }
1110 else if (row_stride > width)
1111 goto error;
1112 }
1113
1114 buf_size = width * height;
1115 buf = malloc (buf_size);
1116 if (buf == NULL)
1117 return 0;
1118
1119 p_in = (char *) pixels_in;
1120 p_out = buf;
1121 row_stride = 0;
1122 row_no = 0;
1123 for (col = 0; col < pixels_in_sz; col++)
1124 {
1125 /* decoding the buffer */
1126 byte = *p_in++;
1127 if (byte < 0)
1128 {
1129 px = 0;
1130 cnt = byte * -1;
1131 }
1132 else
1133 {
1134 px = 1;
1135 cnt = byte + 1;
1136 }
1137 for (i = 0; i < cnt; i++)
1138 *p_out++ = px;
1139 }
1140
1141 *pixels = buf;
1142 *pixels_sz = buf_size;
1143 return 1;
1144 error:
1145 return 0;
1146 }
1147
1148 static int
pack_1bit_rows(rl2PrivRasterPtr raster,unsigned char * in,int * xrow_stride,unsigned char ** pixels,int * size)1149 pack_1bit_rows (rl2PrivRasterPtr raster, unsigned char *in, int *xrow_stride,
1150 unsigned char **pixels, int *size)
1151 {
1152 /* creating a packed 1-BIT pixel buffer */
1153 int row_stride = 0;
1154 unsigned char *pix_buf = NULL;
1155 int pix_size;
1156 unsigned int row;
1157 unsigned int col;
1158 int cnt = 0;
1159 unsigned char *p_in = in;
1160
1161 /* computing the required sizes */
1162 for (col = 0; col < raster->width; col++)
1163 {
1164 if (cnt == 0)
1165 row_stride++;
1166 if (cnt == 7)
1167 cnt = 0;
1168 else
1169 cnt++;
1170 }
1171 pix_size = raster->height * row_stride;
1172
1173 /* allocating the pixel buffers */
1174 pix_buf = malloc (pix_size);
1175 if (pix_buf == NULL)
1176 return 0;
1177
1178 /* pixels packing */
1179 for (row = 0; row < raster->height; row++)
1180 {
1181 unsigned char *p_out = pix_buf + (row_stride * row);
1182 unsigned char packed = 0x00;
1183 unsigned char pixel;
1184 cnt = 0;
1185 for (col = 0; col < raster->width; col++)
1186 {
1187 pixel = *p_in++;
1188 switch (cnt)
1189 {
1190 case 0:
1191 if (pixel != 0)
1192 packed |= 0x80;
1193 break;
1194 case 1:
1195 if (pixel != 0)
1196 packed |= 0x40;
1197 break;
1198 case 2:
1199 if (pixel != 0)
1200 packed |= 0x20;
1201 break;
1202 case 3:
1203 if (pixel != 0)
1204 packed |= 0x10;
1205 break;
1206 case 4:
1207 if (pixel != 0)
1208 packed |= 0x08;
1209 break;
1210 case 5:
1211 if (pixel != 0)
1212 packed |= 0x04;
1213 break;
1214 case 6:
1215 if (pixel != 0)
1216 packed |= 0x02;
1217 break;
1218 case 7:
1219 if (pixel != 0)
1220 packed |= 0x01;
1221 break;
1222 };
1223 if (cnt == 7)
1224 {
1225 *p_out++ = packed;
1226 packed = 0x00;
1227 cnt = 0;
1228 }
1229 else
1230 cnt++;
1231 }
1232 if (cnt != 0)
1233 *p_out++ = packed;
1234 }
1235
1236 *xrow_stride = row_stride;
1237 *pixels = pix_buf;
1238 *size = pix_size;
1239 return 1;
1240 }
1241
1242 static int
pack_2bit_rows(rl2PrivRasterPtr raster,int * xrow_stride,unsigned char ** pixels,int * size)1243 pack_2bit_rows (rl2PrivRasterPtr raster, int *xrow_stride,
1244 unsigned char **pixels, int *size)
1245 {
1246 /* creating a packed 2-BIT pixel buffer */
1247 int row_stride = 0;
1248 unsigned char *pix_buf = NULL;
1249 int pix_size;
1250 unsigned int row;
1251 unsigned int col;
1252 int cnt = 0;
1253 unsigned char *p_in = raster->rasterBuffer;
1254
1255 /* computing the required sizes */
1256 for (col = 0; col < raster->width; col++)
1257 {
1258 if (cnt == 0)
1259 row_stride++;
1260 if (cnt == 3)
1261 cnt = 0;
1262 else
1263 cnt++;
1264 }
1265 pix_size = raster->height * row_stride;
1266
1267 /* allocating the pixel buffers */
1268 pix_buf = malloc (pix_size);
1269 if (pix_buf == NULL)
1270 return 0;
1271
1272 /* pixels packing */
1273 for (row = 0; row < raster->height; row++)
1274 {
1275 unsigned char *p_out = pix_buf + (row_stride * row);
1276 unsigned char packed = 0x00;
1277 unsigned char pixel;
1278 cnt = 0;
1279 for (col = 0; col < raster->width; col++)
1280 {
1281 pixel = *p_in++;
1282 switch (cnt)
1283 {
1284 case 0:
1285 switch (pixel)
1286 {
1287 case 1:
1288 packed |= 0x40;
1289 break;
1290 case 2:
1291 packed |= 0x80;
1292 break;
1293 case 3:
1294 packed |= 0xc0;
1295 break;
1296 };
1297 break;
1298 case 1:
1299 switch (pixel)
1300 {
1301 case 1:
1302 packed |= 0x10;
1303 break;
1304 case 2:
1305 packed |= 0x20;
1306 break;
1307 case 3:
1308 packed |= 0x30;
1309 break;
1310 };
1311 break;
1312 case 2:
1313 switch (pixel)
1314 {
1315 case 1:
1316 packed |= 0x04;
1317 break;
1318 case 2:
1319 packed |= 0x08;
1320 break;
1321 case 3:
1322 packed |= 0x0c;
1323 break;
1324 };
1325 break;
1326 case 3:
1327 switch (pixel)
1328 {
1329 case 1:
1330 packed |= 0x01;
1331 break;
1332 case 2:
1333 packed |= 0x02;
1334 break;
1335 case 3:
1336 packed |= 0x03;
1337 break;
1338 };
1339 break;
1340 };
1341 if (cnt == 3)
1342 {
1343 *p_out++ = packed;
1344 packed = 0x00;
1345 cnt = 0;
1346 }
1347 else
1348 cnt++;
1349 }
1350 if (cnt != 0)
1351 *p_out++ = packed;
1352 }
1353
1354 *xrow_stride = row_stride;
1355 *pixels = pix_buf;
1356 *size = pix_size;
1357 return 1;
1358 }
1359
1360 static int
pack_4bit_rows(rl2PrivRasterPtr raster,int * xrow_stride,unsigned char ** pixels,int * size)1361 pack_4bit_rows (rl2PrivRasterPtr raster, int *xrow_stride,
1362 unsigned char **pixels, int *size)
1363 {
1364 /* creating a packed 4-BIT pixel buffer */
1365 int row_stride = 0;
1366 unsigned char *pix_buf = NULL;
1367 int pix_size;
1368 unsigned int row;
1369 unsigned int col;
1370 int cnt = 0;
1371 unsigned char *p_in = raster->rasterBuffer;
1372
1373 /* computing the required sizes */
1374 for (col = 0; col < raster->width; col++)
1375 {
1376 if (cnt == 0)
1377 row_stride++;
1378 if (cnt == 1)
1379 cnt = 0;
1380 else
1381 cnt++;
1382 }
1383 pix_size = raster->height * row_stride;
1384
1385 /* allocating the pixel buffers */
1386 pix_buf = malloc (pix_size);
1387 if (pix_buf == NULL)
1388 return 0;
1389
1390 /* pixels packing */
1391 for (row = 0; row < raster->height; row++)
1392 {
1393 unsigned char *p_out = pix_buf + (row_stride * row);
1394 unsigned char packed = 0x00;
1395 unsigned char pixel;
1396 cnt = 0;
1397 for (col = 0; col < raster->width; col++)
1398 {
1399 pixel = *p_in++;
1400 switch (cnt)
1401 {
1402 case 0:
1403 switch (pixel)
1404 {
1405 case 1:
1406 packed |= 0x10;
1407 break;
1408 case 2:
1409 packed |= 0x20;
1410 break;
1411 case 3:
1412 packed |= 0x30;
1413 break;
1414 case 4:
1415 packed |= 0x40;
1416 break;
1417 case 5:
1418 packed |= 0x50;
1419 break;
1420 case 6:
1421 packed |= 0x60;
1422 break;
1423 case 7:
1424 packed |= 0x70;
1425 break;
1426 case 8:
1427 packed |= 0x80;
1428 break;
1429 case 9:
1430 packed |= 0x90;
1431 break;
1432 case 10:
1433 packed |= 0xa0;
1434 break;
1435 case 11:
1436 packed |= 0xb0;
1437 break;
1438 case 12:
1439 packed |= 0xc0;
1440 break;
1441 case 13:
1442 packed |= 0xd0;
1443 break;
1444 case 14:
1445 packed |= 0xe0;
1446 break;
1447 case 15:
1448 packed |= 0xf0;
1449 break;
1450 };
1451 break;
1452 case 1:
1453 switch (pixel)
1454 {
1455 case 1:
1456 packed |= 0x01;
1457 break;
1458 case 2:
1459 packed |= 0x02;
1460 break;
1461 case 3:
1462 packed |= 0x03;
1463 break;
1464 case 4:
1465 packed |= 0x04;
1466 break;
1467 case 5:
1468 packed |= 0x05;
1469 break;
1470 case 6:
1471 packed |= 0x06;
1472 break;
1473 case 7:
1474 packed |= 0x07;
1475 break;
1476 case 8:
1477 packed |= 0x08;
1478 break;
1479 case 9:
1480 packed |= 0x09;
1481 break;
1482 case 10:
1483 packed |= 0x0a;
1484 break;
1485 case 11:
1486 packed |= 0x0b;
1487 break;
1488 case 12:
1489 packed |= 0x0c;
1490 break;
1491 case 13:
1492 packed |= 0x0d;
1493 break;
1494 case 14:
1495 packed |= 0x0e;
1496 break;
1497 case 15:
1498 packed |= 0x0f;
1499 break;
1500 };
1501 break;
1502 };
1503 if (cnt == 1)
1504 {
1505 *p_out++ = packed;
1506 packed = 0x00;
1507 cnt = 0;
1508 }
1509 else
1510 cnt++;
1511 }
1512 if (cnt != 0)
1513 *p_out++ = packed;
1514 }
1515
1516 *xrow_stride = row_stride;
1517 *pixels = pix_buf;
1518 *size = pix_size;
1519 return 1;
1520 }
1521
1522 static void
feed_odd_even_int8(void * in,unsigned int width,unsigned int height,int bands,void * pix_odd,void * pix_even)1523 feed_odd_even_int8 (void *in, unsigned int width, unsigned int height,
1524 int bands, void *pix_odd, void *pix_even)
1525 {
1526 /* feeding Odd/Even pixel buffers - INT8 */
1527 char *p_in;
1528 char *p_odd = pix_odd;
1529 char *p_even = pix_even;
1530 unsigned int row;
1531 unsigned int col;
1532
1533 p_in = in;
1534 for (row = 0; row < height; row += 2)
1535 {
1536 for (col = 0; col < width * bands; col++)
1537 *p_odd++ = *p_in++;
1538 p_in += width * bands;
1539 }
1540
1541 p_in = in;
1542 for (row = 1; row < height; row += 2)
1543 {
1544 p_in += width * bands;
1545 for (col = 0; col < width * bands; col++)
1546 *p_even++ = *p_in++;
1547 }
1548 }
1549
1550 static void
feed_odd_even_uint8(void * in,unsigned int width,unsigned int height,int bands,void * pix_odd,void * pix_even)1551 feed_odd_even_uint8 (void *in, unsigned int width, unsigned int height,
1552 int bands, void *pix_odd, void *pix_even)
1553 {
1554 /* feeding Odd/Even pixel buffers - UINT8 */
1555 unsigned char *p_in;
1556 unsigned char *p_odd = pix_odd;
1557 unsigned char *p_even = pix_even;
1558 unsigned int row;
1559 unsigned int col;
1560
1561 p_in = in;
1562 for (row = 0; row < height; row += 2)
1563 {
1564 for (col = 0; col < width * bands; col++)
1565 *p_odd++ = *p_in++;
1566 p_in += width * bands;
1567 }
1568
1569 p_in = in;
1570 for (row = 1; row < height; row += 2)
1571 {
1572 p_in += width * bands;
1573 for (col = 0; col < width * bands; col++)
1574 *p_even++ = *p_in++;
1575 }
1576 }
1577
1578 static void
feed_odd_even_int16(void * in,unsigned int width,unsigned int height,int bands,void * pix_odd,void * pix_even,int swap)1579 feed_odd_even_int16 (void *in, unsigned int width, unsigned int height,
1580 int bands, void *pix_odd, void *pix_even, int swap)
1581 {
1582 /* feeding Odd/Even pixel buffers - INT16 */
1583 short *p_in;
1584 short *p_odd = pix_odd;
1585 short *p_even = pix_even;
1586 unsigned int row;
1587 unsigned int col;
1588
1589 p_in = in;
1590 for (row = 0; row < height; row += 2)
1591 {
1592 for (col = 0; col < width * bands; col++)
1593 {
1594 if (swap)
1595 *p_odd++ = swapINT16 (*p_in++);
1596 else
1597 *p_odd++ = *p_in++;
1598 }
1599 p_in += width * bands;
1600 }
1601
1602 p_in = in;
1603 for (row = 1; row < height; row += 2)
1604 {
1605 p_in += width * bands;
1606 for (col = 0; col < width * bands; col++)
1607 {
1608 if (swap)
1609 *p_even++ = swapINT16 (*p_in++);
1610 else
1611 *p_even++ = *p_in++;
1612 }
1613 }
1614 }
1615
1616 static void
feed_odd_even_uint16(void * in,unsigned int width,unsigned int height,int bands,void * pix_odd,void * pix_even,int swap)1617 feed_odd_even_uint16 (void *in, unsigned int width, unsigned int height,
1618 int bands, void *pix_odd, void *pix_even, int swap)
1619 {
1620 /* feeding Odd/Even pixel buffers - UINT16 */
1621 unsigned short *p_in;
1622 unsigned short *p_odd = pix_odd;
1623 unsigned short *p_even = pix_even;
1624 unsigned int row;
1625 unsigned int col;
1626
1627 p_in = in;
1628 for (row = 0; row < height; row += 2)
1629 {
1630 for (col = 0; col < width * bands; col++)
1631 {
1632 if (swap)
1633 *p_odd++ = swapUINT16 (*p_in++);
1634 else
1635 *p_odd++ = *p_in++;
1636 }
1637 p_in += width * bands;
1638 }
1639
1640 p_in = in;
1641 for (row = 1; row < height; row += 2)
1642 {
1643 p_in += width * bands;
1644 for (col = 0; col < width * bands; col++)
1645 {
1646 if (swap)
1647 *p_even++ = swapUINT16 (*p_in++);
1648 else
1649 *p_even++ = *p_in++;
1650 }
1651 }
1652 }
1653
1654 static void
feed_odd_even_int32(void * in,unsigned int width,unsigned int height,int bands,void * pix_odd,void * pix_even,int swap)1655 feed_odd_even_int32 (void *in, unsigned int width, unsigned int height,
1656 int bands, void *pix_odd, void *pix_even, int swap)
1657 {
1658 /* feeding Odd/Even pixel buffers - INT32 */
1659 int *p_in;
1660 int *p_odd = pix_odd;
1661 int *p_even = pix_even;
1662 unsigned int row;
1663 unsigned int col;
1664
1665 p_in = in;
1666 for (row = 0; row < height; row += 2)
1667 {
1668 for (col = 0; col < width * bands; col++)
1669 {
1670 if (swap)
1671 *p_odd++ = swapINT32 (*p_in++);
1672 else
1673 *p_odd++ = *p_in++;
1674 }
1675 p_in += width * bands;
1676 }
1677
1678 p_in = in;
1679 for (row = 1; row < height; row += 2)
1680 {
1681 p_in += width * bands;
1682 for (col = 0; col < width * bands; col++)
1683 {
1684 if (swap)
1685 *p_even++ = swapINT32 (*p_in++);
1686 else
1687 *p_even++ = *p_in++;
1688 }
1689 }
1690 }
1691
1692 static void
feed_odd_even_uint32(void * in,unsigned int width,unsigned int height,int bands,void * pix_odd,void * pix_even,int swap)1693 feed_odd_even_uint32 (void *in, unsigned int width, unsigned int height,
1694 int bands, void *pix_odd, void *pix_even, int swap)
1695 {
1696 /* feeding Odd/Even pixel buffers - UINT32 */
1697 unsigned int *p_in;
1698 unsigned int *p_odd = pix_odd;
1699 unsigned int *p_even = pix_even;
1700 unsigned int row;
1701 unsigned int col;
1702
1703 p_in = in;
1704 for (row = 0; row < height; row += 2)
1705 {
1706 for (col = 0; col < width * bands; col++)
1707 {
1708 if (swap)
1709 *p_odd++ = swapUINT32 (*p_in++);
1710 else
1711 *p_odd++ = *p_in++;
1712 }
1713 p_in += width * bands;
1714 }
1715
1716 p_in = in;
1717 for (row = 1; row < height; row += 2)
1718 {
1719 p_in += width * bands;
1720 for (col = 0; col < width * bands; col++)
1721 {
1722 if (swap)
1723 *p_even++ = swapUINT32 (*p_in++);
1724 else
1725 *p_even++ = *p_in++;
1726 }
1727 }
1728 }
1729
1730 static void
feed_odd_even_float(void * in,unsigned int width,unsigned int height,int bands,void * pix_odd,void * pix_even,int swap)1731 feed_odd_even_float (void *in, unsigned int width, unsigned int height,
1732 int bands, void *pix_odd, void *pix_even, int swap)
1733 {
1734 /* feeding Odd/Even pixel buffers - FLOAT */
1735 float *p_in;
1736 float *p_odd = pix_odd;
1737 float *p_even = pix_even;
1738 unsigned int row;
1739 unsigned int col;
1740
1741 p_in = in;
1742 for (row = 0; row < height; row += 2)
1743 {
1744 for (col = 0; col < width * bands; col++)
1745 {
1746 if (swap)
1747 *p_odd++ = swapFloat (*p_in++);
1748 else
1749 *p_odd++ = *p_in++;
1750 }
1751 p_in += width * bands;
1752 }
1753
1754 p_in = in;
1755 for (row = 1; row < height; row += 2)
1756 {
1757 p_in += width * bands;
1758 for (col = 0; col < width * bands; col++)
1759 {
1760 if (swap)
1761 *p_even++ = swapFloat (*p_in++);
1762 else
1763 *p_even++ = *p_in++;
1764 }
1765 }
1766 }
1767
1768 static void
feed_odd_even_double(void * in,unsigned int width,unsigned int height,int bands,void * pix_odd,void * pix_even,int swap)1769 feed_odd_even_double (void *in, unsigned int width, unsigned int height,
1770 int bands, void *pix_odd, void *pix_even, int swap)
1771 {
1772 /* feeding Odd/Even pixel buffers - DOUBLE */
1773 double *p_in;
1774 double *p_odd = pix_odd;
1775 double *p_even = pix_even;
1776 unsigned int row;
1777 unsigned int col;
1778
1779 p_in = in;
1780 for (row = 0; row < height; row += 2)
1781 {
1782 for (col = 0; col < width * bands; col++)
1783 {
1784 if (swap)
1785 *p_odd++ = swapDouble (*p_in++);
1786 else
1787 *p_odd++ = *p_in++;
1788 }
1789 p_in += width * bands;
1790 }
1791
1792 p_in = in;
1793 for (row = 1; row < height; row += 2)
1794 {
1795 p_in += width * bands;
1796 for (col = 0; col < width * bands; col++)
1797 {
1798 if (swap)
1799 *p_even++ = swapDouble (*p_in++);
1800 else
1801 *p_even++ = *p_in++;
1802 }
1803 }
1804 }
1805
1806 static int
odd_even_rows(rl2PrivRasterPtr raster,int * odd_rows,int * row_stride_odd,unsigned char ** pixels_odd,int * size_odd,int * even_rows,int * row_stride_even,unsigned char ** pixels_even,int * size_even,int little_endian)1807 odd_even_rows (rl2PrivRasterPtr raster, int *odd_rows, int *row_stride_odd,
1808 unsigned char **pixels_odd, int *size_odd, int *even_rows,
1809 int *row_stride_even, unsigned char **pixels_even,
1810 int *size_even, int little_endian)
1811 {
1812 /* creating both Odd and Even rows buffers */
1813 int o_rows = 0;
1814 int e_rows = 0;
1815 int o_stride = 0;
1816 int e_stride = 0;
1817 unsigned char *pix_odd = NULL;
1818 unsigned char *pix_even = NULL;
1819 int o_size;
1820 int e_size;
1821 unsigned int row;
1822 int pix_size;
1823 int swap = 0;
1824 if (little_endian != endianArch ())
1825 swap = 1;
1826 else
1827 swap = 0;
1828
1829 /* computing the required sizes */
1830 for (row = 0; row < raster->height; row += 2)
1831 o_rows++;
1832 for (row = 1; row < raster->height; row += 2)
1833 e_rows++;
1834 switch (raster->sampleType)
1835 {
1836 case RL2_SAMPLE_INT8:
1837 case RL2_SAMPLE_UINT8:
1838 pix_size = 1;
1839 break;
1840 case RL2_SAMPLE_INT16:
1841 case RL2_SAMPLE_UINT16:
1842 pix_size = 2;
1843 break;
1844 case RL2_SAMPLE_INT32:
1845 case RL2_SAMPLE_UINT32:
1846 case RL2_SAMPLE_FLOAT:
1847 pix_size = 4;
1848 break;
1849 case RL2_SAMPLE_DOUBLE:
1850 pix_size = 8;
1851 break;
1852 };
1853 o_size = raster->width * o_rows * pix_size * raster->nBands;
1854 e_size = raster->width * e_rows * pix_size * raster->nBands;
1855 o_stride = raster->width * pix_size * raster->nBands;
1856 e_stride = o_stride;
1857
1858 /* allocating the pixel buffers */
1859 pix_odd = malloc (o_size);
1860 if (pix_odd == NULL)
1861 return 0;
1862 pix_even = malloc (e_size);
1863 if (pix_even == NULL)
1864 {
1865 free (pix_odd);
1866 return 0;
1867 }
1868 memset (pix_odd, 0, o_size);
1869 memset (pix_even, 0, e_size);
1870
1871 /* feeding the pixel buffers */
1872 switch (raster->sampleType)
1873 {
1874 case RL2_SAMPLE_INT8:
1875 feed_odd_even_int8 (raster->rasterBuffer, raster->width,
1876 raster->height, raster->nBands, pix_odd,
1877 pix_even);
1878 break;
1879 case RL2_SAMPLE_UINT8:
1880 feed_odd_even_uint8 (raster->rasterBuffer, raster->width,
1881 raster->height, raster->nBands, pix_odd,
1882 pix_even);
1883 break;
1884 case RL2_SAMPLE_INT16:
1885 feed_odd_even_int16 (raster->rasterBuffer, raster->width,
1886 raster->height, raster->nBands, pix_odd,
1887 pix_even, swap);
1888 break;
1889 case RL2_SAMPLE_UINT16:
1890 feed_odd_even_uint16 (raster->rasterBuffer, raster->width,
1891 raster->height, raster->nBands, pix_odd,
1892 pix_even, swap);
1893 break;
1894 case RL2_SAMPLE_INT32:
1895 feed_odd_even_int32 (raster->rasterBuffer, raster->width,
1896 raster->height, raster->nBands, pix_odd,
1897 pix_even, swap);
1898 break;
1899 case RL2_SAMPLE_UINT32:
1900 feed_odd_even_uint32 (raster->rasterBuffer, raster->width,
1901 raster->height, raster->nBands, pix_odd,
1902 pix_even, swap);
1903 break;
1904 case RL2_SAMPLE_FLOAT:
1905 feed_odd_even_float (raster->rasterBuffer, raster->width,
1906 raster->height, raster->nBands, pix_odd,
1907 pix_even, swap);
1908 break;
1909 case RL2_SAMPLE_DOUBLE:
1910 feed_odd_even_double (raster->rasterBuffer, raster->width,
1911 raster->height, raster->nBands, pix_odd,
1912 pix_even, swap);
1913 break;
1914 };
1915 *odd_rows = o_rows;
1916 *even_rows = e_rows;
1917 *row_stride_odd = o_stride;
1918 *row_stride_even = e_stride;
1919 *pixels_odd = pix_odd;
1920 *pixels_even = pix_even;
1921 *size_odd = o_size;
1922 *size_even = e_size;
1923 return 1;
1924 }
1925
1926 RL2_DECLARE int
rl2_raster_encode(rl2RasterPtr rst,int compression,unsigned char ** blob_odd,int * blob_odd_sz,unsigned char ** blob_even,int * blob_even_sz,int quality,int little_endian)1927 rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
1928 int *blob_odd_sz, unsigned char **blob_even,
1929 int *blob_even_sz, int quality, int little_endian)
1930 {
1931 /* encoding a Raster into the internal RL2 binary format */
1932 rl2PrivRasterPtr raster = (rl2PrivRasterPtr) rst;
1933 int odd_rows;
1934 unsigned char *pixels_odd = NULL;
1935 int size_odd;
1936 int even_rows = 0;
1937 unsigned char *pixels_even = NULL;
1938 int size_even = 0;
1939 int row_stride_odd = 0;
1940 unsigned char *mask_pix = NULL;
1941 int mask_pix_size = 0;
1942 unsigned char *block_odd = NULL;
1943 int block_odd_size = 0;
1944 int row_stride_even = 0;
1945 unsigned char *block_even = NULL;
1946 int block_even_size = 0;
1947 unsigned char *ptr;
1948 int uncompressed;
1949 int compressed;
1950 int uncompressed_mask = 0;
1951 int compressed_mask = 0;
1952 unsigned char *compr_data = NULL;
1953 unsigned char *compr_mask = NULL;
1954 unsigned char *to_clean1 = NULL;
1955 unsigned char *to_clean2 = NULL;
1956 unsigned char *save_mask = NULL;
1957 uLong crc;
1958 int endian_arch = endianArch ();
1959
1960 *blob_odd = NULL;
1961 *blob_odd_sz = 0;
1962 *blob_even = NULL;
1963 *blob_even_sz = 0;
1964
1965 if (raster == NULL)
1966 return RL2_ERROR;
1967 if (!check_encode_self_consistency
1968 (raster->sampleType, raster->pixelType, raster->nBands, compression))
1969 return RL2_ERROR;
1970
1971 if (compression == RL2_COMPRESSION_NONE
1972 || compression == RL2_COMPRESSION_DEFLATE
1973 || compression == RL2_COMPRESSION_LZMA)
1974 {
1975 /* preparing the pixels buffers */
1976 if (raster->sampleType == RL2_SAMPLE_1_BIT)
1977 {
1978 /* packing 1-BIT data */
1979 if (!pack_1bit_rows
1980 (raster, raster->rasterBuffer, &row_stride_odd, &pixels_odd,
1981 &size_odd))
1982 return RL2_ERROR;
1983 odd_rows = raster->height;
1984 }
1985 else if (raster->sampleType == RL2_SAMPLE_2_BIT)
1986 {
1987 /* packing 2-BIT data */
1988 if (!pack_2bit_rows
1989 (raster, &row_stride_odd, &pixels_odd, &size_odd))
1990 return RL2_ERROR;
1991 odd_rows = raster->height;
1992 }
1993 else if (raster->sampleType == RL2_SAMPLE_4_BIT)
1994 {
1995 /* packing 4-BIT data */
1996 if (!pack_4bit_rows
1997 (raster, &row_stride_odd, &pixels_odd, &size_odd))
1998 return RL2_ERROR;
1999 odd_rows = raster->height;
2000 }
2001 else
2002 {
2003 /* Odd/Even raster */
2004 if (!odd_even_rows
2005 (raster, &odd_rows, &row_stride_odd, &pixels_odd, &size_odd,
2006 &even_rows, &row_stride_even, &pixels_even, &size_even,
2007 little_endian))
2008 return RL2_ERROR;
2009 }
2010 }
2011 else if (compression == RL2_COMPRESSION_PNG)
2012 {
2013 if (raster->sampleType == RL2_SAMPLE_1_BIT
2014 || raster->sampleType == RL2_SAMPLE_2_BIT
2015 || raster->sampleType == RL2_SAMPLE_4_BIT)
2016 {
2017 /* no special action is required */
2018 }
2019 else
2020 {
2021 /* Odd/Even raster */
2022 if (!odd_even_rows
2023 (raster, &odd_rows, &row_stride_odd, &pixels_odd, &size_odd,
2024 &even_rows, &row_stride_even, &pixels_even, &size_even,
2025 little_endian))
2026 return RL2_ERROR;
2027 }
2028 }
2029 else if (compression == RL2_COMPRESSION_JPEG
2030 || compression == RL2_COMPRESSION_LOSSY_WEBP
2031 || compression == RL2_COMPRESSION_LOSSLESS_WEBP
2032 || compression == RL2_COMPRESSION_CCITTFAX4)
2033 {
2034 /* no special action is required */
2035 }
2036 else
2037 return RL2_ERROR;
2038 if (raster->maskBuffer != NULL)
2039 {
2040 /* preparing the mask buffer */
2041 save_mask = raster->maskBuffer;
2042 raster->maskBuffer = NULL;
2043 /* packing RLE data */
2044 if (!pack_rle_rows (raster, save_mask, &mask_pix, &mask_pix_size))
2045 return RL2_ERROR;
2046 }
2047
2048 if (compression == RL2_COMPRESSION_NONE)
2049 {
2050 uncompressed = size_odd;
2051 compressed = size_odd;
2052 compr_data = pixels_odd;
2053 if (mask_pix == NULL)
2054 uncompressed_mask = 0;
2055 else
2056 uncompressed_mask = raster->width * raster->height;
2057 compressed_mask = mask_pix_size;
2058 compr_mask = mask_pix;
2059 }
2060 else if (compression == RL2_COMPRESSION_DEFLATE)
2061 {
2062 /* compressing as ZIP [Deflate] */
2063 int ret;
2064 uLong zLen = size_odd - 1;
2065 unsigned char *zip_buf = malloc (zLen);
2066 if (zip_buf == NULL)
2067 goto error;
2068 ret =
2069 compress (zip_buf, &zLen, (const Bytef *) pixels_odd,
2070 (uLong) size_odd);
2071 if (ret == Z_OK)
2072 {
2073 /* ok, ZIP compression was successful */
2074 uncompressed = size_odd;
2075 compressed = (int) zLen;
2076 compr_data = zip_buf;
2077 to_clean1 = zip_buf;
2078 }
2079 else if (ret == Z_BUF_ERROR)
2080 {
2081 /* ZIP compression actually causes inflation: saving uncompressed data */
2082 uncompressed = size_odd;
2083 compressed = size_odd;
2084 compr_data = pixels_odd;
2085 free (zip_buf);
2086 zip_buf = NULL;
2087 }
2088 else
2089 {
2090 /* compression error */
2091 free (zip_buf);
2092 goto error;
2093 }
2094 if (mask_pix == NULL)
2095 uncompressed_mask = 0;
2096 else
2097 uncompressed_mask = raster->width * raster->height;
2098 compressed_mask = mask_pix_size;
2099 compr_mask = mask_pix;
2100 }
2101 else if (compression == RL2_COMPRESSION_LZMA)
2102 {
2103 /* compressing as LZMA */
2104 lzma_options_lzma opt_lzma2;
2105 lzma_ret ret;
2106 lzma_filter filters[2];
2107 size_t out_pos = 0;
2108 size_t lzmaLen = size_odd - 1;
2109 unsigned char *lzma_buf = malloc (lzmaLen);
2110 if (lzma_buf == NULL)
2111 goto error;
2112 lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
2113 filters[0].id = LZMA_FILTER_LZMA2;
2114 filters[0].options = &opt_lzma2;
2115 filters[1].id = LZMA_VLI_UNKNOWN;
2116 filters[1].options = NULL;
2117 ret =
2118 lzma_raw_buffer_encode (filters, NULL,
2119 (const uint8_t *) pixels_odd, size_odd,
2120 lzma_buf, &out_pos, lzmaLen);
2121 if (ret == LZMA_OK)
2122 {
2123 /* ok, LZMA compression was successful */
2124 uncompressed = size_odd;
2125 compressed = (int) out_pos;
2126 compr_data = lzma_buf;
2127 to_clean1 = lzma_buf;
2128 }
2129 else if (ret == LZMA_BUF_ERROR)
2130 {
2131 /* LZMA compression actually causes inflation: saving uncompressed data */
2132 uncompressed = size_odd;
2133 compressed = size_odd;
2134 compr_data = pixels_odd;
2135 free (lzma_buf);
2136 lzma_buf = NULL;
2137 }
2138 else
2139 {
2140 /* compression error */
2141 free (lzma_buf);
2142 goto error;
2143 }
2144 if (mask_pix == NULL)
2145 uncompressed_mask = 0;
2146 else
2147 uncompressed_mask = raster->width * raster->height;
2148 compressed_mask = mask_pix_size;
2149 compr_mask = mask_pix;
2150 }
2151 else if (compression == RL2_COMPRESSION_JPEG)
2152 {
2153 /* compressing as JPEG */
2154 if (rl2_raster_to_jpeg (rst, &compr_data, &compressed, quality) ==
2155 RL2_OK)
2156 {
2157 /* ok, JPEG compression was successful */
2158 uncompressed = raster->width * raster->height * raster->nBands;
2159 to_clean1 = compr_data;
2160 }
2161 else
2162 goto error;
2163 odd_rows = raster->height;
2164 if (mask_pix == NULL)
2165 uncompressed_mask = 0;
2166 else
2167 uncompressed_mask = raster->width * raster->height;
2168 compressed_mask = mask_pix_size;
2169 compr_mask = mask_pix;
2170 }
2171 else if (compression == RL2_COMPRESSION_LOSSLESS_WEBP)
2172 {
2173 /* compressing as lossless WEBP */
2174 if (rl2_raster_to_lossless_webp (rst, &compr_data, &compressed) ==
2175 RL2_OK)
2176 {
2177 /* ok, lossless WEBP compression was successful */
2178 uncompressed = raster->width * raster->height * raster->nBands;
2179 to_clean1 = compr_data;
2180 }
2181 else
2182 goto error;
2183 odd_rows = raster->height;
2184 if (mask_pix == NULL)
2185 uncompressed_mask = 0;
2186 else
2187 uncompressed_mask = raster->width * raster->height;
2188 compressed_mask = mask_pix_size;
2189 compr_mask = mask_pix;
2190 }
2191 else if (compression == RL2_COMPRESSION_LOSSY_WEBP)
2192 {
2193 /* compressing as lossy WEBP */
2194 if (rl2_raster_to_lossy_webp (rst, &compr_data, &compressed, quality)
2195 == RL2_OK)
2196 {
2197 /* ok, lossy WEBP compression was successful */
2198 uncompressed = raster->width * raster->height * raster->nBands;
2199 to_clean1 = compr_data;
2200 }
2201 else
2202 goto error;
2203 odd_rows = raster->height;
2204 if (mask_pix == NULL)
2205 uncompressed_mask = 0;
2206 else
2207 uncompressed_mask = raster->width * raster->height;
2208 compressed_mask = mask_pix_size;
2209 compr_mask = mask_pix;
2210 }
2211 else if (compression == RL2_COMPRESSION_PNG)
2212 {
2213 /* compressing as PNG */
2214 if (raster->sampleType == RL2_SAMPLE_1_BIT
2215 || raster->sampleType == RL2_SAMPLE_2_BIT
2216 || raster->sampleType == RL2_SAMPLE_4_BIT)
2217 {
2218 /* solid ODD block */
2219 if (rl2_raster_to_png (rst, &compr_data, &compressed) == RL2_OK)
2220 {
2221 /* ok, PNG compression was successful */
2222 uncompressed = raster->width * raster->height;
2223 to_clean1 = compr_data;
2224 odd_rows = raster->height;
2225 if (mask_pix == NULL)
2226 uncompressed_mask = 0;
2227 else
2228 uncompressed_mask = raster->width * raster->height;
2229 compressed_mask = mask_pix_size;
2230 compr_mask = mask_pix;
2231 }
2232 else
2233 goto error;
2234 }
2235 else
2236 {
2237 /* split between Odd/Even Blocks */
2238 rl2PalettePtr plt = rl2_get_raster_palette (rst);
2239 if (rl2_data_to_png
2240 (pixels_odd, NULL, 1.0, plt, raster->width,
2241 odd_rows, raster->sampleType, raster->pixelType,
2242 &compr_data, &compressed) == RL2_OK)
2243 {
2244 /* ok, PNG compression was successful */
2245 uncompressed = size_odd;
2246 to_clean1 = compr_data;
2247 if (mask_pix == NULL)
2248 uncompressed_mask = 0;
2249 else
2250 uncompressed_mask = raster->width * raster->height;
2251 compressed_mask = mask_pix_size;
2252 compr_mask = mask_pix;
2253 }
2254 else
2255 goto error;
2256 }
2257 }
2258 else if (compression == RL2_COMPRESSION_CCITTFAX4)
2259 {
2260 /* compressing as TIFF FAX4 */
2261 if (rl2_raster_to_tiff_mono4
2262 (rst, &compr_data, &compressed) == RL2_OK)
2263 {
2264 /* ok, TIFF compression was successful */
2265 uncompressed = raster->width * raster->height;
2266 to_clean1 = compr_data;
2267 odd_rows = raster->height;
2268 if (mask_pix == NULL)
2269 uncompressed_mask = 0;
2270 else
2271 uncompressed_mask = raster->width * raster->height;
2272 compressed_mask = mask_pix_size;
2273 compr_mask = mask_pix;
2274 }
2275 else
2276 goto error;
2277 }
2278
2279 /* preparing the OddBlock */
2280 block_odd_size = 40 + compressed + compressed_mask;
2281 block_odd = malloc (block_odd_size);
2282 if (block_odd == NULL)
2283 goto error;
2284 ptr = block_odd;
2285 *ptr++ = 0x00; /* start marker */
2286 *ptr++ = RL2_ODD_BLOCK_START; /* OddBlock marker */
2287 if (little_endian) /* endian marker */
2288 *ptr++ = RL2_LITTLE_ENDIAN;
2289 else
2290 *ptr++ = RL2_BIG_ENDIAN;
2291 *ptr++ = compression; /* compression marker */
2292 *ptr++ = raster->sampleType; /* sample type marker */
2293 *ptr++ = raster->pixelType; /* pixel type marker */
2294 *ptr++ = raster->nBands; /* # Bands marker */
2295 exportU16 (ptr, raster->width, little_endian, endian_arch); /* the raster width */
2296 ptr += 2;
2297 exportU16 (ptr, raster->height, little_endian, endian_arch); /* the raster height */
2298 ptr += 2;
2299 exportU16 (ptr, row_stride_odd, little_endian, endian_arch); /* the block row stride */
2300 ptr += 2;
2301 exportU16 (ptr, odd_rows, little_endian, endian_arch); /* block #rows */
2302 ptr += 2;
2303 exportU32 (ptr, uncompressed, little_endian, endian_arch); /* uncompressed payload size in bytes */
2304 ptr += 4;
2305 exportU32 (ptr, compressed, little_endian, endian_arch); /* compressed payload size in bytes */
2306 ptr += 4;
2307 exportU32 (ptr, uncompressed_mask, little_endian, endian_arch); /* uncompressed mask size in bytes */
2308 ptr += 4;
2309 exportU32 (ptr, compressed_mask, little_endian, endian_arch); /* compressed mask size in bytes */
2310 ptr += 4;
2311 *ptr++ = RL2_DATA_START;
2312 memcpy (ptr, compr_data, compressed); /* the payload */
2313 ptr += compressed;
2314 *ptr++ = RL2_DATA_END;
2315 *ptr++ = RL2_MASK_START;
2316 if (compr_mask != NULL)
2317 {
2318 memcpy (ptr, compr_mask, compressed_mask); /* the mask */
2319 ptr += compressed_mask;
2320 }
2321 *ptr++ = RL2_MASK_END;
2322 /* computing the CRC32 */
2323 crc = crc32 (0L, block_odd, ptr - block_odd);
2324 exportU32 (ptr, crc, little_endian, endian_arch); /* the OddBlock own CRC */
2325 ptr += 4;
2326 *ptr = RL2_ODD_BLOCK_END;
2327
2328 if (size_even)
2329 {
2330 /* preparing the EvenBlock */
2331 if (compression == RL2_COMPRESSION_NONE)
2332 {
2333 uncompressed = size_even;
2334 compressed = size_even;
2335 compr_data = pixels_even;
2336 }
2337 else if (compression == RL2_COMPRESSION_DEFLATE)
2338 {
2339 /* compressing as ZIP [Deflate] */
2340 int ret;
2341 uLong zLen = compressBound (size_even);
2342 unsigned char *zip_buf = malloc (zLen);
2343 if (zip_buf == NULL)
2344 goto error;
2345 ret =
2346 compress (zip_buf, &zLen, (const Bytef *) pixels_even,
2347 (uLong) size_even);
2348 if (ret == Z_OK)
2349 {
2350 /* ok, ZIP compression was successful */
2351 uncompressed = size_even;
2352 compressed = (int) zLen;
2353 compr_data = zip_buf;
2354 to_clean2 = zip_buf;
2355 }
2356 else if (ret == Z_BUF_ERROR)
2357 {
2358 /* ZIP compression actually causes inflation: saving uncompressed data */
2359 uncompressed = size_even;
2360 compressed = size_even;
2361 compr_data = pixels_even;
2362 free (zip_buf);
2363 zip_buf = NULL;
2364 }
2365 else
2366 {
2367 /* compression error */
2368 free (zip_buf);
2369 goto error;
2370 }
2371 }
2372 else if (compression == RL2_COMPRESSION_LZMA)
2373 {
2374 /* compressing as LZMA */
2375 lzma_options_lzma opt_lzma2;
2376 lzma_ret ret;
2377 lzma_filter filters[2];
2378 size_t out_pos = 0;
2379 size_t lzmaLen = size_even - 1;
2380 unsigned char *lzma_buf = malloc (lzmaLen);
2381 if (lzma_buf == NULL)
2382 goto error;
2383 lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
2384 filters[0].id = LZMA_FILTER_LZMA2;
2385 filters[0].options = &opt_lzma2;
2386 filters[1].id = LZMA_VLI_UNKNOWN;
2387 filters[1].options = NULL;
2388 ret =
2389 lzma_raw_buffer_encode (filters, NULL,
2390 (const uint8_t *) pixels_even,
2391 size_even, lzma_buf, &out_pos,
2392 lzmaLen);
2393 if (ret == LZMA_OK)
2394 {
2395 /* ok, LZMA compression was successful */
2396 uncompressed = size_even;
2397 compressed = (int) out_pos;
2398 compr_data = lzma_buf;
2399 to_clean2 = lzma_buf;
2400 }
2401 else if (ret == LZMA_BUF_ERROR)
2402 {
2403 /* LZMA compression actually causes inflation: saving uncompressed data */
2404 uncompressed = size_even;
2405 compressed = size_even;
2406 compr_data = pixels_even;
2407 free (lzma_buf);
2408 lzma_buf = NULL;
2409 }
2410 else
2411 {
2412 /* compression error */
2413 free (lzma_buf);
2414 goto error;
2415 }
2416 }
2417 else if (compression == RL2_COMPRESSION_PNG)
2418 {
2419 /* compressing as PNG */
2420 if (raster->sampleType == RL2_SAMPLE_1_BIT
2421 || raster->sampleType == RL2_SAMPLE_2_BIT
2422 || raster->sampleType == RL2_SAMPLE_4_BIT)
2423 ;
2424 else
2425 {
2426 /* split between Odd/Even Blocks */
2427 rl2PalettePtr plt = rl2_get_raster_palette (rst);
2428 if (rl2_data_to_png
2429 (pixels_even, NULL, 1.0, plt, raster->width,
2430 even_rows, raster->sampleType, raster->pixelType,
2431 &compr_data, &compressed) == RL2_OK)
2432 {
2433 /* ok, PNG compression was successful */
2434 uncompressed = size_even;
2435 to_clean2 = compr_data;
2436 }
2437 else
2438 goto error;
2439 }
2440 }
2441 block_even_size = 32 + compressed;
2442 block_even = malloc (block_even_size);
2443 if (block_even == NULL)
2444 goto error;
2445 ptr = block_even;
2446 *ptr++ = 0x00; /* start marker */
2447 *ptr++ = RL2_EVEN_BLOCK_START; /* EvenBlock marker */
2448 if (little_endian) /* endian marker */
2449 *ptr++ = RL2_LITTLE_ENDIAN;
2450 else
2451 *ptr++ = RL2_BIG_ENDIAN;
2452 *ptr++ = compression; /* compression marker */
2453 *ptr++ = raster->sampleType; /* sample type marker */
2454 *ptr++ = raster->pixelType; /* pixel type marker */
2455 *ptr++ = raster->nBands; /* # Bands marker */
2456 exportU16 (ptr, raster->width, little_endian, endian_arch); /* the raster width */
2457 ptr += 2;
2458 exportU16 (ptr, raster->height, little_endian, endian_arch); /* the raster height */
2459 ptr += 2;
2460 exportU16 (ptr, even_rows, little_endian, endian_arch); /* block #rows */
2461 ptr += 2;
2462 exportU32 (ptr, crc, little_endian, endian_arch); /* the OddBlock own CRC */
2463 ptr += 4;
2464 exportU32 (ptr, uncompressed, little_endian, endian_arch); /* uncompressed payload size in bytes */
2465 ptr += 4;
2466 exportU32 (ptr, compressed, little_endian, endian_arch); /* compressed payload size in bytes */
2467 ptr += 4;
2468 *ptr++ = RL2_DATA_START;
2469 memcpy (ptr, compr_data, compressed); /* the payload */
2470 ptr += compressed;
2471 *ptr++ = RL2_DATA_END;
2472 /* computing the CRC32 */
2473 crc = crc32 (0L, block_even, ptr - block_even);
2474 exportU32 (ptr, crc, little_endian, endian_arch); /* the EvenBlock own CRC */
2475 ptr += 4;
2476 *ptr = RL2_EVEN_BLOCK_END;
2477 }
2478
2479 if (pixels_odd != NULL)
2480 free (pixels_odd);
2481 if (pixels_even != NULL)
2482 free (pixels_even);
2483 if (mask_pix != NULL)
2484 free (mask_pix);
2485 if (to_clean1 != NULL)
2486 free (to_clean1);
2487 if (to_clean2 != NULL)
2488 free (to_clean2);
2489
2490 raster->maskBuffer = save_mask;
2491 *blob_odd = block_odd;
2492 *blob_odd_sz = block_odd_size;
2493 *blob_even = block_even;
2494 *blob_even_sz = block_even_size;
2495 return RL2_OK;
2496
2497 error:
2498 if (pixels_odd != NULL)
2499 free (pixels_odd);
2500 if (pixels_even != NULL)
2501 free (pixels_even);
2502 if (mask_pix != NULL)
2503 free (mask_pix);
2504 if (to_clean1 != NULL)
2505 free (to_clean1);
2506 if (to_clean2 != NULL)
2507 free (to_clean2);
2508 if (block_odd != NULL)
2509 free (block_odd);
2510 if (block_even != NULL)
2511 free (block_even);
2512 raster->maskBuffer = save_mask;
2513 return RL2_ERROR;
2514 }
2515
2516 static int
check_blob_odd(const unsigned char * blob,int blob_sz,unsigned int * xwidth,unsigned int * xheight,unsigned char * xsample_type,unsigned char * xpixel_type,unsigned char * xnum_bands,unsigned char * xcompression,uLong * xcrc)2517 check_blob_odd (const unsigned char *blob, int blob_sz, unsigned int *xwidth,
2518 unsigned int *xheight, unsigned char *xsample_type,
2519 unsigned char *xpixel_type, unsigned char *xnum_bands,
2520 unsigned char *xcompression, uLong * xcrc)
2521 {
2522 /* checking the OddBlock for validity */
2523 const unsigned char *ptr;
2524 unsigned short width;
2525 unsigned short height;
2526 unsigned char sample_type;
2527 unsigned char pixel_type;
2528 unsigned char num_bands;
2529 unsigned char compression;
2530 int compressed;
2531 int compressed_mask;
2532 uLong crc;
2533 uLong oldCrc;
2534 int endian;
2535 int endian_arch = endianArch ();
2536
2537 if (blob_sz < 41)
2538 return 0;
2539 ptr = blob;
2540 if (*ptr++ != 0x00)
2541 return 0; /* invalid start signature */
2542 if (*ptr++ != RL2_ODD_BLOCK_START)
2543 return 0; /* invalid start signature */
2544 endian = *ptr++;
2545 if (endian == RL2_LITTLE_ENDIAN || endian == RL2_BIG_ENDIAN)
2546 ;
2547 else
2548 return 0; /* invalid endiannes */
2549 compression = *ptr++; /* compression */
2550 switch (compression)
2551 {
2552 case RL2_COMPRESSION_NONE:
2553 case RL2_COMPRESSION_DEFLATE:
2554 case RL2_COMPRESSION_LZMA:
2555 case RL2_COMPRESSION_PNG:
2556 case RL2_COMPRESSION_JPEG:
2557 case RL2_COMPRESSION_LOSSY_WEBP:
2558 case RL2_COMPRESSION_LOSSLESS_WEBP:
2559 case RL2_COMPRESSION_CCITTFAX4:
2560 break;
2561 default:
2562 return 0;
2563 };
2564 sample_type = *ptr++; /* sample type */
2565 switch (sample_type)
2566 {
2567 case RL2_SAMPLE_1_BIT:
2568 case RL2_SAMPLE_2_BIT:
2569 case RL2_SAMPLE_4_BIT:
2570 case RL2_SAMPLE_INT8:
2571 case RL2_SAMPLE_UINT8:
2572 case RL2_SAMPLE_INT16:
2573 case RL2_SAMPLE_UINT16:
2574 case RL2_SAMPLE_INT32:
2575 case RL2_SAMPLE_UINT32:
2576 case RL2_SAMPLE_FLOAT:
2577 case RL2_SAMPLE_DOUBLE:
2578 break;
2579 default:
2580 return 0;
2581 };
2582 pixel_type = *ptr++; /* pixel type */
2583 switch (pixel_type)
2584 {
2585 case RL2_PIXEL_MONOCHROME:
2586 case RL2_PIXEL_PALETTE:
2587 case RL2_PIXEL_GRAYSCALE:
2588 case RL2_PIXEL_RGB:
2589 case RL2_PIXEL_MULTIBAND:
2590 case RL2_PIXEL_DATAGRID:
2591 break;
2592 default:
2593 return 0;
2594 };
2595 num_bands = *ptr++; /* # Bands */
2596 width = importU16 (ptr, endian, endian_arch);
2597 ptr += 2;
2598 height = importU16 (ptr, endian, endian_arch);
2599 ptr += 2;
2600 ptr += 4; /* skipping */
2601 ptr += 4; /* skipping the uncompressed payload size */
2602 compressed = importU32 (ptr, endian, endian_arch);
2603 ptr += 4;
2604 ptr += 4; /* skipping the uncompressed mask size */
2605 compressed_mask = importU32 (ptr, endian, endian_arch);
2606 ptr += 4;
2607 if (*ptr++ != RL2_DATA_START)
2608 return 0;
2609 if (blob_sz < 40 + compressed + compressed_mask)
2610 return 0;
2611 ptr += compressed;
2612 if (*ptr++ != RL2_DATA_END)
2613 return 0;
2614 if (*ptr++ != RL2_MASK_START)
2615 return 0;
2616 ptr += compressed_mask;
2617 if (*ptr++ != RL2_MASK_END)
2618 return 0;
2619 /* computing the CRC32 */
2620 crc = crc32 (0L, blob, ptr - blob);
2621 oldCrc = importU32 (ptr, endian, endian_arch);
2622 ptr += 4;
2623 if (crc != oldCrc)
2624 return 0;
2625 if (*ptr != RL2_ODD_BLOCK_END)
2626 return 0; /* invalid end signature */
2627
2628 *xwidth = width;
2629 *xheight = height;
2630 *xsample_type = sample_type;
2631 *xpixel_type = pixel_type;
2632 *xnum_bands = num_bands;
2633 *xcompression = compression;
2634 *xcrc = crc;
2635 return 1;
2636 }
2637
2638 static int
check_blob_even(const unsigned char * blob,int blob_sz,unsigned short xwidth,unsigned short xheight,unsigned char xsample_type,unsigned char xpixel_type,unsigned char xnum_bands,unsigned char xcompression,uLong xcrc)2639 check_blob_even (const unsigned char *blob, int blob_sz, unsigned short xwidth,
2640 unsigned short xheight, unsigned char xsample_type,
2641 unsigned char xpixel_type, unsigned char xnum_bands,
2642 unsigned char xcompression, uLong xcrc)
2643 {
2644 /* checking the EvenBlock for validity */
2645 const unsigned char *ptr;
2646 unsigned short width;
2647 unsigned short height;
2648 unsigned char sample_type;
2649 unsigned char pixel_type;
2650 unsigned char num_bands;
2651 unsigned char compression;
2652 int compressed;
2653 uLong crc;
2654 uLong oldCrc;
2655 int endian;
2656 int endian_arch = endianArch ();
2657
2658 if (blob_sz < 33)
2659 return 0;
2660 ptr = blob;
2661 if (*ptr++ != 0x00)
2662 return 0; /* invalid start signature */
2663 if (*ptr++ != RL2_EVEN_BLOCK_START)
2664 return 0; /* invalid start signature */
2665 endian = *ptr++;
2666 if (endian == RL2_LITTLE_ENDIAN || endian == RL2_BIG_ENDIAN)
2667 ;
2668 else
2669 return 0; /* invalid endiannes */
2670 compression = *ptr++; /* compression */
2671 if (xcompression != compression)
2672 return 0;
2673 sample_type = *ptr++; /* sample type */
2674 if (xsample_type != sample_type)
2675 return 0;
2676 pixel_type = *ptr++; /* pixel type */
2677 if (xpixel_type != pixel_type)
2678 return 0;
2679 num_bands = *ptr++; /* # Bands */
2680 if (num_bands != xnum_bands)
2681 return 0;
2682 width = importU16 (ptr, endian, endian_arch);
2683 ptr += 2;
2684 if (xwidth != width)
2685 return 0;
2686 height = importU16 (ptr, endian, endian_arch);
2687 ptr += 2;
2688 if (xheight != height)
2689 return 0;
2690 ptr += 2; /* skipping block # rows */
2691 crc = importU32 (ptr, endian, endian_arch);
2692 ptr += 4;
2693 if (xcrc != crc)
2694 return 0;
2695 ptr += 4; /* skipping the uncompressed payload size */
2696 compressed = importU32 (ptr, endian, endian_arch);
2697 ptr += 4;
2698 if (*ptr++ != RL2_DATA_START)
2699 return 0;
2700 if (blob_sz < 32 + compressed)
2701 return 0;
2702 ptr += compressed;
2703 if (*ptr++ != RL2_DATA_END)
2704 return 0;
2705 /* computing the CRC32 */
2706 crc = crc32 (0L, blob, ptr - blob);
2707 oldCrc = importU32 (ptr, endian, endian_arch);
2708 ptr += 4;
2709 if (crc != oldCrc)
2710 return 0;
2711 if (*ptr != RL2_EVEN_BLOCK_END)
2712 return 0; /* invalid end signature */
2713 return 1;
2714 }
2715
2716 static int
check_scale(int scale,unsigned char sample_type,unsigned char compression,const unsigned char * blob_even)2717 check_scale (int scale, unsigned char sample_type, unsigned char compression,
2718 const unsigned char *blob_even)
2719 {
2720 /* checking if the encoded raster could be decoded at given scale */
2721 switch (scale)
2722 {
2723 case RL2_SCALE_1:
2724 if (sample_type == RL2_SAMPLE_1_BIT || sample_type == RL2_SAMPLE_2_BIT
2725 || sample_type == RL2_SAMPLE_4_BIT)
2726 ;
2727 else if (compression == RL2_COMPRESSION_JPEG
2728 || compression == RL2_COMPRESSION_LOSSY_WEBP
2729 || compression == RL2_COMPRESSION_LOSSLESS_WEBP
2730 || compression == RL2_COMPRESSION_CCITTFAX4)
2731 {
2732 if (blob_even != NULL)
2733 return 0;
2734 }
2735 else if (blob_even == NULL)
2736 return 0;
2737 break;
2738 case RL2_SCALE_2:
2739 case RL2_SCALE_4:
2740 case RL2_SCALE_8:
2741 break;
2742 default:
2743 return 0;
2744 };
2745 switch (sample_type)
2746 {
2747 case RL2_SAMPLE_1_BIT:
2748 case RL2_SAMPLE_2_BIT:
2749 case RL2_SAMPLE_4_BIT:
2750 if (scale != RL2_SCALE_1)
2751 return 0;
2752 break;
2753 };
2754 return 1;
2755 }
2756
2757 static void
do_copy2_int8(const char * p_odd,char * buf,unsigned int width,unsigned int odd_rows)2758 do_copy2_int8 (const char *p_odd, char *buf, unsigned int width,
2759 unsigned int odd_rows)
2760 {
2761 /* reassembling an INT8 raster - scale 1:2 */
2762 unsigned int row;
2763 unsigned int col;
2764 char *p_out;
2765
2766 p_out = buf;
2767 for (row = 0; row < odd_rows; row++)
2768 {
2769 for (col = 0; col < width; col += 2)
2770 *p_out++ = *p_odd++;
2771 p_odd++;
2772 }
2773 }
2774
2775 static void
do_copy2_uint8(const unsigned char * p_odd,unsigned char * buf,unsigned int width,unsigned int odd_rows,unsigned char num_bands)2776 do_copy2_uint8 (const unsigned char *p_odd, unsigned char *buf,
2777 unsigned int width, unsigned int odd_rows,
2778 unsigned char num_bands)
2779 {
2780 /* reassembling a UINT8 raster - scale 1:2 */
2781 unsigned int row;
2782 unsigned int col;
2783 int band;
2784 unsigned char *p_out;
2785
2786 p_out = buf;
2787 for (row = 0; row < odd_rows; row++)
2788 {
2789 for (col = 0; col < width; col += 2)
2790 {
2791 for (band = 0; band < num_bands; band++)
2792 *p_out++ = *p_odd++;
2793 p_odd += num_bands;
2794 }
2795 }
2796 }
2797
2798 static void
do_copy2_int16(int swap,const short * p_odd,short * buf,unsigned int width,unsigned int odd_rows)2799 do_copy2_int16 (int swap, const short *p_odd, short *buf, unsigned int width,
2800 unsigned int odd_rows)
2801 {
2802 /* reassembling an INT16 raster - scale 1:2 */
2803 unsigned int row;
2804 unsigned int col;
2805 short *p_out;
2806
2807 p_out = buf;
2808 for (row = 0; row < odd_rows; row++)
2809 {
2810 for (col = 0; col < width; col += 2)
2811 {
2812 if (swap)
2813 *p_out++ = swapINT16 (*p_odd++);
2814 else
2815 *p_out++ = *p_odd++;
2816 p_odd++;
2817 }
2818 }
2819 }
2820
2821 static void
do_copy2_uint16(int swap,const unsigned short * p_odd,unsigned short * buf,unsigned int width,unsigned int odd_rows,unsigned char num_bands)2822 do_copy2_uint16 (int swap, const unsigned short *p_odd, unsigned short *buf,
2823 unsigned int width, unsigned int odd_rows,
2824 unsigned char num_bands)
2825 {
2826 /* reassembling a UINT16 raster - scale 1:2 */
2827 unsigned int row;
2828 unsigned int col;
2829 int band;
2830 unsigned short *p_out;
2831
2832 p_out = buf;
2833 for (row = 0; row < odd_rows; row++)
2834 {
2835 for (col = 0; col < width; col += 2)
2836 {
2837 for (band = 0; band < num_bands; band++)
2838 {
2839 if (swap)
2840 *p_out++ = swapUINT16 (*p_odd++);
2841 else
2842 *p_out++ = *p_odd++;
2843 }
2844 p_odd += num_bands;
2845 }
2846 }
2847 }
2848
2849 static void
do_copy2_int32(int swap,const int * p_odd,int * buf,unsigned int width,unsigned int odd_rows)2850 do_copy2_int32 (int swap, const int *p_odd, int *buf, unsigned int width,
2851 unsigned int odd_rows)
2852 {
2853 /* reassembling an INT32 raster - scale 1:2 */
2854 unsigned int row;
2855 unsigned int col;
2856 int *p_out;
2857
2858 p_out = buf;
2859 for (row = 0; row < odd_rows; row++)
2860 {
2861 for (col = 0; col < width; col += 2)
2862 {
2863 if (swap)
2864 *p_out++ = swapINT32 (*p_odd++);
2865 else
2866 *p_out++ = *p_odd++;
2867 p_odd++;
2868 }
2869 }
2870 }
2871
2872 static void
do_copy2_uint32(int swap,const unsigned int * p_odd,unsigned int * buf,unsigned int width,unsigned int odd_rows)2873 do_copy2_uint32 (int swap, const unsigned int *p_odd, unsigned int *buf,
2874 unsigned int width, unsigned int odd_rows)
2875 {
2876 /* reassembling an UINT32 raster - scale 1:2 */
2877 unsigned int row;
2878 unsigned int col;
2879 unsigned int *p_out;
2880
2881 p_out = buf;
2882 for (row = 0; row < odd_rows; row++)
2883 {
2884 for (col = 0; col < width; col += 2)
2885 {
2886 if (swap)
2887 *p_out++ = swapUINT32 (*p_odd++);
2888 else
2889 *p_out++ = *p_odd++;
2890 p_odd++;
2891 }
2892 }
2893 }
2894
2895 static void
do_copy2_float(int swap,const float * p_odd,float * buf,unsigned int width,unsigned int odd_rows)2896 do_copy2_float (int swap, const float *p_odd, float *buf, unsigned int width,
2897 unsigned int odd_rows)
2898 {
2899 /* reassembling a FLOAT raster - scale 1:2 */
2900 unsigned int row;
2901 unsigned int col;
2902 float *p_out;
2903
2904 p_out = buf;
2905 for (row = 0; row < odd_rows; row++)
2906 {
2907 for (col = 0; col < width; col += 2)
2908 {
2909 if (swap)
2910 *p_out++ = swapFloat (*p_odd++);
2911 else
2912 *p_out++ = *p_odd++;
2913 p_odd++;
2914 }
2915 }
2916 }
2917
2918 static void
do_copy2_double(int swap,const double * p_odd,double * buf,unsigned int width,unsigned int odd_rows)2919 do_copy2_double (int swap, const double *p_odd, double *buf,
2920 unsigned int width, unsigned int odd_rows)
2921 {
2922 /* reassembling a FLOAT raster - scale 1:2 */
2923 unsigned int row;
2924 unsigned int col;
2925 double *p_out;
2926
2927 p_out = buf;
2928 for (row = 0; row < odd_rows; row++)
2929 {
2930 for (col = 0; col < width; col += 2)
2931 {
2932 if (swap)
2933 *p_out++ = swapDouble (*p_odd++);
2934 else
2935 *p_out++ = *p_odd++;
2936 p_odd++;
2937 }
2938 }
2939 }
2940
2941 static int
build_pixel_buffer_2(int swap,unsigned int * xwidth,unsigned int * xheight,unsigned char sample_type,unsigned char pixel_size,unsigned char num_bands,unsigned short odd_rows,const void * pixels_odd,void ** pixels,int * pixels_sz)2942 build_pixel_buffer_2 (int swap, unsigned int *xwidth, unsigned int *xheight,
2943 unsigned char sample_type, unsigned char pixel_size,
2944 unsigned char num_bands, unsigned short odd_rows,
2945 const void *pixels_odd, void **pixels, int *pixels_sz)
2946 {
2947 /* decoding the raster - scale 1:2 */
2948 unsigned int width = 0;
2949 unsigned int height = 0;
2950 unsigned int row;
2951 unsigned int col;
2952 void *buf;
2953 int buf_size;
2954
2955 for (row = 0; row < *xheight; row += 2)
2956 height++;
2957 for (col = 0; col < *xwidth; col += 2)
2958 width++;
2959
2960 buf_size = width * height * pixel_size * num_bands;
2961 buf = malloc (buf_size);
2962 if (buf == NULL)
2963 return 0;
2964
2965 switch (sample_type)
2966 {
2967 case RL2_SAMPLE_INT8:
2968 do_copy2_int8 (pixels_odd, buf, *xwidth, odd_rows);
2969 break;
2970 case RL2_SAMPLE_UINT8:
2971 do_copy2_uint8 (pixels_odd, buf, *xwidth, odd_rows, num_bands);
2972 break;
2973 case RL2_SAMPLE_INT16:
2974 do_copy2_int16 (swap, pixels_odd, buf, *xwidth, odd_rows);
2975 break;
2976 case RL2_SAMPLE_UINT16:
2977 do_copy2_uint16 (swap, pixels_odd, buf, *xwidth, odd_rows, num_bands);
2978 break;
2979 case RL2_SAMPLE_INT32:
2980 do_copy2_int32 (swap, pixels_odd, buf, *xwidth, odd_rows);
2981 break;
2982 case RL2_SAMPLE_UINT32:
2983 do_copy2_uint32 (swap, pixels_odd, buf, *xwidth, odd_rows);
2984 break;
2985 case RL2_SAMPLE_FLOAT:
2986 do_copy2_float (swap, pixels_odd, buf, *xwidth, odd_rows);
2987 break;
2988 case RL2_SAMPLE_DOUBLE:
2989 do_copy2_double (swap, pixels_odd, buf, *xwidth, odd_rows);
2990 break;
2991 };
2992
2993 *xwidth = width;
2994 *xheight = height;
2995 *pixels = buf;
2996 *pixels_sz = buf_size;
2997 return 1;
2998 }
2999
3000 static void
do_copy4_int8(const char * p_odd,char * buf,unsigned int width,unsigned int odd_rows)3001 do_copy4_int8 (const char *p_odd, char *buf, unsigned int width,
3002 unsigned int odd_rows)
3003 {
3004 /* reassembling an INT8 raster - scale 1:4 */
3005 unsigned int row;
3006 unsigned int col;
3007 char *p_out;
3008
3009 p_out = buf;
3010 for (row = 0; row < odd_rows; row += 2)
3011 {
3012 for (col = 0; col < width; col += 4)
3013 {
3014 *p_out++ = *p_odd++;
3015 p_odd += 3;
3016 }
3017 p_odd += width;
3018 }
3019 }
3020
3021 static void
do_copy4_uint8(const unsigned char * p_odd,unsigned char * buf,unsigned int width,unsigned int odd_rows,unsigned char num_bands)3022 do_copy4_uint8 (const unsigned char *p_odd, unsigned char *buf,
3023 unsigned int width, unsigned int odd_rows,
3024 unsigned char num_bands)
3025 {
3026 /* reassembling a UINT8 raster - scale 1:4 */
3027 unsigned int row;
3028 unsigned int col;
3029 int band;
3030 unsigned char *p_out;
3031
3032 p_out = buf;
3033 for (row = 0; row < odd_rows; row += 2)
3034 {
3035 for (col = 0; col < width; col += 4)
3036 {
3037 for (band = 0; band < num_bands; band++)
3038 *p_out++ = *p_odd++;
3039 p_odd += num_bands * 3;
3040 }
3041 p_odd += width * num_bands;
3042 }
3043 }
3044
3045 static void
do_copy4_int16(int swap,const short * p_odd,short * buf,unsigned int width,unsigned int odd_rows)3046 do_copy4_int16 (int swap, const short *p_odd, short *buf, unsigned int width,
3047 unsigned int odd_rows)
3048 {
3049 /* reassembling an INT16 raster - scale 1:4 */
3050 unsigned int row;
3051 unsigned int col;
3052 short *p_out;
3053
3054 p_out = buf;
3055 for (row = 0; row < odd_rows; row += 2)
3056 {
3057 for (col = 0; col < width; col += 4)
3058 {
3059 if (swap)
3060 *p_out++ = swapINT16 (*p_odd++);
3061 else
3062 *p_out++ = *p_odd++;
3063 p_odd += 3;
3064 }
3065 p_odd += width;
3066 }
3067 }
3068
3069 static void
do_copy4_uint16(int swap,const unsigned short * p_odd,unsigned short * buf,unsigned int width,unsigned int odd_rows,unsigned char num_bands)3070 do_copy4_uint16 (int swap, const unsigned short *p_odd, unsigned short *buf,
3071 unsigned int width, unsigned int odd_rows,
3072 unsigned char num_bands)
3073 {
3074 /* reassembling a UINT16 raster - scale 1:4 */
3075 unsigned int row;
3076 unsigned int col;
3077 int band;
3078 unsigned short *p_out;
3079
3080 p_out = buf;
3081 for (row = 0; row < odd_rows; row += 2)
3082 {
3083 for (col = 0; col < width; col += 4)
3084 {
3085 for (band = 0; band < num_bands; band++)
3086 {
3087 if (swap)
3088 *p_out++ = swapUINT16 (*p_odd++);
3089 else
3090 *p_out++ = *p_odd++;
3091 }
3092 p_odd += num_bands * 3;
3093 }
3094 p_odd += width * num_bands;
3095 }
3096 }
3097
3098 static void
do_copy4_int32(int swap,const int * p_odd,int * buf,unsigned int width,unsigned int odd_rows)3099 do_copy4_int32 (int swap, const int *p_odd, int *buf, unsigned int width,
3100 unsigned int odd_rows)
3101 {
3102 /* reassembling an INT32 raster - scale 1:4 */
3103 unsigned int row;
3104 unsigned int col;
3105 int *p_out;
3106
3107 p_out = buf;
3108 for (row = 0; row < odd_rows; row += 2)
3109 {
3110 for (col = 0; col < width; col += 4)
3111 {
3112 if (swap)
3113 *p_out++ = swapINT32 (*p_odd++);
3114 else
3115 *p_out++ = *p_odd++;
3116 p_odd += 3;
3117 }
3118 p_odd += width;
3119 }
3120 }
3121
3122 static void
do_copy4_uint32(int swap,const unsigned int * p_odd,unsigned int * buf,unsigned int width,unsigned int odd_rows)3123 do_copy4_uint32 (int swap, const unsigned int *p_odd, unsigned int *buf,
3124 unsigned int width, unsigned int odd_rows)
3125 {
3126 /* reassembling an UINT32 raster - scale 1:4 */
3127 unsigned int row;
3128 unsigned int col;
3129 unsigned int *p_out;
3130
3131 p_out = buf;
3132 for (row = 0; row < odd_rows; row += 2)
3133 {
3134 for (col = 0; col < width; col += 4)
3135 {
3136 if (swap)
3137 *p_out++ = swapUINT32 (*p_odd++);
3138 else
3139 *p_out++ = *p_odd++;
3140 p_odd += 3;
3141 }
3142 p_odd += width;
3143 }
3144 }
3145
3146 static void
do_copy4_float(int swap,const float * p_odd,float * buf,unsigned int width,unsigned int odd_rows)3147 do_copy4_float (int swap, const float *p_odd, float *buf, unsigned int width,
3148 unsigned int odd_rows)
3149 {
3150 /* reassembling a FLOAT raster - scale 1:4 */
3151 unsigned int row;
3152 unsigned int col;
3153 float *p_out;
3154
3155 p_out = buf;
3156 for (row = 0; row < odd_rows; row += 2)
3157 {
3158 for (col = 0; col < width; col += 4)
3159 {
3160 if (swap)
3161 *p_out++ = swapFloat (*p_odd++);
3162 else
3163 *p_out++ = *p_odd++;
3164 p_odd += 3;
3165 }
3166 p_odd += width;
3167 }
3168 }
3169
3170 static void
do_copy4_double(int swap,const double * p_odd,double * buf,unsigned int width,unsigned int odd_rows)3171 do_copy4_double (int swap, const double *p_odd, double *buf,
3172 unsigned int width, unsigned int odd_rows)
3173 {
3174 /* reassembling a DOUBLE raster - scale 1:4 */
3175 unsigned int row;
3176 unsigned int col;
3177 double *p_out;
3178
3179 p_out = buf;
3180 for (row = 0; row < odd_rows; row += 2)
3181 {
3182 for (col = 0; col < width; col += 4)
3183 {
3184 if (swap)
3185 *p_out++ = swapDouble (*p_odd++);
3186 else
3187 *p_out++ = *p_odd++;
3188 p_odd += 3;
3189 }
3190 p_odd += width;
3191 }
3192 }
3193
3194 static int
build_pixel_buffer_4(int swap,unsigned int * xwidth,unsigned int * xheight,unsigned char sample_type,unsigned char pixel_size,unsigned char num_bands,unsigned int odd_rows,const void * pixels_odd,void ** pixels,int * pixels_sz)3195 build_pixel_buffer_4 (int swap, unsigned int *xwidth, unsigned int *xheight,
3196 unsigned char sample_type, unsigned char pixel_size,
3197 unsigned char num_bands, unsigned int odd_rows,
3198 const void *pixels_odd, void **pixels, int *pixels_sz)
3199 {
3200 /* decoding the raster - scale 1:4 */
3201 unsigned short width = 0;
3202 unsigned short height = 0;
3203 unsigned int row;
3204 unsigned int col;
3205 void *buf;
3206 int buf_size;
3207
3208 for (row = 0; row < *xheight; row += 4)
3209 height++;
3210 for (col = 0; col < *xwidth; col += 4)
3211 width++;
3212
3213 buf_size = width * height * pixel_size * num_bands;
3214 buf = malloc (buf_size);
3215 if (buf == NULL)
3216 return 0;
3217
3218 switch (sample_type)
3219 {
3220 case RL2_SAMPLE_INT8:
3221 do_copy4_int8 (pixels_odd, buf, *xwidth, odd_rows);
3222 break;
3223 case RL2_SAMPLE_UINT8:
3224 do_copy4_uint8 (pixels_odd, buf, *xwidth, odd_rows, num_bands);
3225 break;
3226 case RL2_SAMPLE_INT16:
3227 do_copy4_int16 (swap, pixels_odd, buf, *xwidth, odd_rows);
3228 break;
3229 case RL2_SAMPLE_UINT16:
3230 do_copy4_uint16 (swap, pixels_odd, buf, *xwidth, odd_rows, num_bands);
3231 break;
3232 case RL2_SAMPLE_INT32:
3233 do_copy4_int32 (swap, pixels_odd, buf, *xwidth, odd_rows);
3234 break;
3235 case RL2_SAMPLE_UINT32:
3236 do_copy4_uint32 (swap, pixels_odd, buf, *xwidth, odd_rows);
3237 break;
3238 case RL2_SAMPLE_FLOAT:
3239 do_copy4_float (swap, pixels_odd, buf, *xwidth, odd_rows);
3240 break;
3241 case RL2_SAMPLE_DOUBLE:
3242 do_copy4_double (swap, pixels_odd, buf, *xwidth, odd_rows);
3243 break;
3244 };
3245
3246 *xwidth = width;
3247 *xheight = height;
3248 *pixels = buf;
3249 *pixels_sz = buf_size;
3250 return 1;
3251 }
3252
3253 static void
do_copy8_int8(const char * p_odd,char * buf,unsigned int width,unsigned int odd_rows)3254 do_copy8_int8 (const char *p_odd, char *buf, unsigned int width,
3255 unsigned int odd_rows)
3256 {
3257 /* reassembling an INT8 raster - scale 1:8 */
3258 unsigned int row;
3259 unsigned int col;
3260 char *p_out;
3261
3262 p_out = buf;
3263 for (row = 0; row < odd_rows; row += 4)
3264 {
3265 for (col = 0; col < width; col += 8)
3266 {
3267 *p_out++ = *p_odd++;
3268 p_odd += 7;
3269 }
3270 p_odd += 3 * width;
3271 }
3272 }
3273
3274 static void
do_copy8_uint8(const unsigned char * p_odd,unsigned char * buf,unsigned int width,unsigned int odd_rows,unsigned char num_bands)3275 do_copy8_uint8 (const unsigned char *p_odd, unsigned char *buf,
3276 unsigned int width, unsigned int odd_rows,
3277 unsigned char num_bands)
3278 {
3279 /* reassembling a UINT8 raster - scale 1:8 */
3280 unsigned int row;
3281 unsigned int col;
3282 int band;
3283 unsigned char *p_out;
3284
3285 p_out = buf;
3286 for (row = 0; row < odd_rows; row += 4)
3287 {
3288 for (col = 0; col < width; col += 8)
3289 {
3290 for (band = 0; band < num_bands; band++)
3291 *p_out++ = *p_odd++;
3292 p_odd += num_bands * 7;
3293 }
3294 p_odd += 3 * width * num_bands;
3295 }
3296 }
3297
3298 static void
do_copy8_int16(int swap,const short * p_odd,short * buf,unsigned int width,unsigned int odd_rows)3299 do_copy8_int16 (int swap, const short *p_odd, short *buf, unsigned int width,
3300 unsigned int odd_rows)
3301 {
3302 /* reassembling an INT16 raster - scale 1:8 */
3303 unsigned int row;
3304 unsigned int col;
3305 short *p_out;
3306
3307 p_out = buf;
3308 for (row = 0; row < odd_rows; row += 4)
3309 {
3310 for (col = 0; col < width; col += 8)
3311 {
3312 if (swap)
3313 *p_out++ = swapINT16 (*p_odd++);
3314 else
3315 *p_out++ = *p_odd++;
3316 p_odd += 7;
3317 }
3318 p_odd += 3 * width;
3319 }
3320 }
3321
3322 static void
do_copy8_uint16(int swap,const unsigned short * p_odd,unsigned short * buf,unsigned int width,unsigned int odd_rows,unsigned char num_bands)3323 do_copy8_uint16 (int swap, const unsigned short *p_odd, unsigned short *buf,
3324 unsigned int width, unsigned int odd_rows,
3325 unsigned char num_bands)
3326 {
3327 /* reassembling a UINT16 raster - scale 1:8 */
3328 unsigned int row;
3329 unsigned int col;
3330 int band;
3331 unsigned short *p_out;
3332
3333 p_out = buf;
3334 for (row = 0; row < odd_rows; row += 4)
3335 {
3336 for (col = 0; col < width; col += 8)
3337 {
3338 for (band = 0; band < num_bands; band++)
3339 {
3340 if (swap)
3341 *p_out++ = swapUINT16 (*p_odd++);
3342 else
3343 *p_out++ = *p_odd++;
3344 }
3345 p_odd += num_bands * 7;
3346 }
3347 p_odd += 3 * width * num_bands;
3348 }
3349 }
3350
3351 static void
do_copy8_int32(int swap,const int * p_odd,int * buf,unsigned int width,unsigned int odd_rows)3352 do_copy8_int32 (int swap, const int *p_odd, int *buf, unsigned int width,
3353 unsigned int odd_rows)
3354 {
3355 /* reassembling an INT32 raster - scale 1:8 */
3356 unsigned int row;
3357 unsigned int col;
3358 int *p_out;
3359
3360 p_out = buf;
3361 for (row = 0; row < odd_rows; row += 4)
3362 {
3363 for (col = 0; col < width; col += 8)
3364 {
3365 if (swap)
3366 *p_out++ = swapINT32 (*p_odd++);
3367 else
3368 *p_out++ = *p_odd++;
3369 p_odd += 7;
3370 }
3371 p_odd += 3 * width;
3372 }
3373 }
3374
3375 static void
do_copy8_uint32(int swap,const unsigned int * p_odd,unsigned int * buf,unsigned short width,unsigned short odd_rows)3376 do_copy8_uint32 (int swap, const unsigned int *p_odd, unsigned int *buf,
3377 unsigned short width, unsigned short odd_rows)
3378 {
3379 /* reassembling an UINT32 raster - scale 1:8 */
3380 int row;
3381 int col;
3382 unsigned int *p_out;
3383
3384 p_out = buf;
3385 for (row = 0; row < odd_rows; row += 4)
3386 {
3387 for (col = 0; col < width; col += 8)
3388 {
3389 if (swap)
3390 *p_out++ = swapUINT32 (*p_odd++);
3391 else
3392 *p_out++ = *p_odd++;
3393 p_odd += 7;
3394 }
3395 p_odd += 3 * width;
3396 }
3397 }
3398
3399 static void
do_copy8_float(int swap,const float * p_odd,float * buf,unsigned int width,unsigned int odd_rows)3400 do_copy8_float (int swap, const float *p_odd, float *buf, unsigned int width,
3401 unsigned int odd_rows)
3402 {
3403 /* reassembling a FLOAT raster - scale 1:8 */
3404 unsigned int row;
3405 unsigned int col;
3406 float *p_out;
3407
3408 p_out = buf;
3409 for (row = 0; row < odd_rows; row += 4)
3410 {
3411 for (col = 0; col < width; col += 8)
3412 {
3413 if (swap)
3414 *p_out++ = swapFloat (*p_odd++);
3415 else
3416 *p_out++ = *p_odd++;
3417 p_odd += 7;
3418 }
3419 p_odd += 3 * width;
3420 }
3421 }
3422
3423 static void
do_copy8_double(int swap,const double * p_odd,double * buf,unsigned int width,unsigned int odd_rows)3424 do_copy8_double (int swap, const double *p_odd, double *buf,
3425 unsigned int width, unsigned int odd_rows)
3426 {
3427 /* reassembling a DOUBLE raster - scale 1:8 */
3428 unsigned int row;
3429 unsigned int col;
3430 double *p_out;
3431
3432 p_out = buf;
3433 for (row = 0; row < odd_rows; row += 4)
3434 {
3435 for (col = 0; col < width; col += 8)
3436 {
3437 if (swap)
3438 *p_out++ = swapDouble (*p_odd++);
3439 else
3440 *p_out++ = *p_odd++;
3441 p_odd += 7;
3442 }
3443 p_odd += 3 * width;
3444 }
3445 }
3446
3447 static int
build_pixel_buffer_8(int swap,unsigned int * xwidth,unsigned int * xheight,unsigned char sample_type,unsigned char pixel_size,unsigned char num_bands,unsigned short odd_rows,const void * pixels_odd,void ** pixels,int * pixels_sz)3448 build_pixel_buffer_8 (int swap, unsigned int *xwidth, unsigned int *xheight,
3449 unsigned char sample_type, unsigned char pixel_size,
3450 unsigned char num_bands, unsigned short odd_rows,
3451 const void *pixels_odd, void **pixels, int *pixels_sz)
3452 {
3453 /* decoding the raster - scale 1:8 */
3454 unsigned int width = 0;
3455 unsigned int height = 0;
3456 unsigned int row;
3457 unsigned int col;
3458 void *buf;
3459 int buf_size;
3460
3461 for (row = 0; row < *xheight; row += 8)
3462 height++;
3463 for (col = 0; col < *xwidth; col += 8)
3464 width++;
3465
3466 buf_size = width * height * pixel_size * num_bands;
3467 buf = malloc (buf_size);
3468 if (buf == NULL)
3469 return 0;
3470
3471 switch (sample_type)
3472 {
3473 case RL2_SAMPLE_INT8:
3474 do_copy8_int8 (pixels_odd, buf, *xwidth, odd_rows);
3475 break;
3476 case RL2_SAMPLE_UINT8:
3477 do_copy8_uint8 (pixels_odd, buf, *xwidth, odd_rows, num_bands);
3478 break;
3479 case RL2_SAMPLE_INT16:
3480 do_copy8_int16 (swap, pixels_odd, buf, *xwidth, odd_rows);
3481 break;
3482 case RL2_SAMPLE_UINT16:
3483 do_copy8_uint16 (swap, pixels_odd, buf, *xwidth, odd_rows, num_bands);
3484 break;
3485 case RL2_SAMPLE_INT32:
3486 do_copy8_int32 (swap, pixels_odd, buf, *xwidth, odd_rows);
3487 break;
3488 case RL2_SAMPLE_UINT32:
3489 do_copy8_uint32 (swap, pixels_odd, buf, *xwidth, odd_rows);
3490 break;
3491 case RL2_SAMPLE_FLOAT:
3492 do_copy8_float (swap, pixels_odd, buf, *xwidth, odd_rows);
3493 break;
3494 case RL2_SAMPLE_DOUBLE:
3495 do_copy8_double (swap, pixels_odd, buf, *xwidth, odd_rows);
3496 break;
3497 };
3498
3499 *xwidth = width;
3500 *xheight = height;
3501 *pixels = buf;
3502 *pixels_sz = buf_size;
3503 return 1;
3504 }
3505
3506 static void
do_copy_int8(const char * p_odd,const char * p_even,char * buf,unsigned short width,unsigned short odd_rows,unsigned short even_rows)3507 do_copy_int8 (const char *p_odd, const char *p_even, char *buf,
3508 unsigned short width, unsigned short odd_rows,
3509 unsigned short even_rows)
3510 {
3511 /* reassembling an INT8 raster - scale 1:1 */
3512 int row;
3513 int col;
3514 char *p_out;
3515
3516 p_out = buf;
3517 for (row = 0; row < odd_rows; row++)
3518 {
3519 /* Odd scanlines */
3520 for (col = 0; col < width; col++)
3521 *p_out++ = *p_odd++;
3522 p_out += width;
3523 }
3524
3525 p_out = buf;
3526 for (row = 0; row < even_rows; row++)
3527 {
3528 /* Even scanlines */
3529 p_out += width;
3530 for (col = 0; col < width; col++)
3531 *p_out++ = *p_even++;
3532 }
3533 }
3534
3535 static void
do_copy_uint8(const unsigned char * p_odd,const unsigned char * p_even,unsigned char * buf,unsigned short width,unsigned short odd_rows,unsigned short even_rows,unsigned char num_bands)3536 do_copy_uint8 (const unsigned char *p_odd, const unsigned char *p_even,
3537 unsigned char *buf, unsigned short width,
3538 unsigned short odd_rows, unsigned short even_rows,
3539 unsigned char num_bands)
3540 {
3541 /* reassembling a UINT8 raster - scale 1:1 */
3542 int row;
3543 int col;
3544 int band;
3545 unsigned char *p_out;
3546
3547 p_out = buf;
3548 for (row = 0; row < odd_rows; row++)
3549 {
3550 /* Odd scanlines */
3551 for (col = 0; col < width; col++)
3552 {
3553 for (band = 0; band < num_bands; band++)
3554 *p_out++ = *p_odd++;
3555 }
3556 p_out += width * num_bands;
3557 }
3558
3559 p_out = buf;
3560 for (row = 0; row < even_rows; row++)
3561 {
3562 /* Even scanlines */
3563 p_out += width * num_bands;
3564 for (col = 0; col < width; col++)
3565 {
3566 for (band = 0; band < num_bands; band++)
3567 *p_out++ = *p_even++;
3568 }
3569 }
3570 }
3571
3572 static void
do_copy_int16(int swap,const short * p_odd,const short * p_even,short * buf,unsigned short width,unsigned short odd_rows,unsigned short even_rows)3573 do_copy_int16 (int swap, const short *p_odd, const short *p_even, short *buf,
3574 unsigned short width, unsigned short odd_rows,
3575 unsigned short even_rows)
3576 {
3577 /* reassembling an INT16 raster - scale 1:1 */
3578 int row;
3579 int col;
3580 short *p_out;
3581
3582 p_out = buf;
3583 for (row = 0; row < odd_rows; row++)
3584 {
3585 /* Odd scanlines */
3586 for (col = 0; col < width; col++)
3587 {
3588 if (swap)
3589 *p_out++ = swapINT16 (*p_odd++);
3590 else
3591 *p_out++ = *p_odd++;
3592 }
3593 p_out += width;
3594 }
3595
3596 p_out = buf;
3597 for (row = 0; row < even_rows; row++)
3598 {
3599 /* Even scanlines */
3600 p_out += width;
3601 for (col = 0; col < width; col++)
3602 {
3603 if (swap)
3604 *p_out++ = swapINT16 (*p_even++);
3605 else
3606 *p_out++ = *p_even++;
3607 }
3608 }
3609 }
3610
3611 static void
do_copy_uint16(int swap,const unsigned short * p_odd,const unsigned short * p_even,unsigned short * buf,unsigned short width,unsigned short odd_rows,unsigned short even_rows,unsigned char num_bands)3612 do_copy_uint16 (int swap, const unsigned short *p_odd,
3613 const unsigned short *p_even, unsigned short *buf,
3614 unsigned short width, unsigned short odd_rows,
3615 unsigned short even_rows, unsigned char num_bands)
3616 {
3617 /* reassembling a UINT16 raster - scale 1:1 */
3618 int row;
3619 int col;
3620 int band;
3621 unsigned short *p_out;
3622
3623 p_out = buf;
3624 for (row = 0; row < odd_rows; row++)
3625 {
3626 /* Odd scanlines */
3627 for (col = 0; col < width; col++)
3628 {
3629 for (band = 0; band < num_bands; band++)
3630 {
3631 if (swap)
3632 *p_out++ = swapUINT16 (*p_odd++);
3633 else
3634 *p_out++ = *p_odd++;
3635 }
3636 }
3637 p_out += width * num_bands;
3638 }
3639
3640 p_out = buf;
3641 for (row = 0; row < even_rows; row++)
3642 {
3643 /* Even scanlines */
3644 p_out += width * num_bands;
3645 for (col = 0; col < width; col++)
3646 {
3647 for (band = 0; band < num_bands; band++)
3648 {
3649 if (swap)
3650 *p_out++ = swapUINT16 (*p_even++);
3651 else
3652 *p_out++ = *p_even++;
3653 }
3654 }
3655 }
3656 }
3657
3658 static void
do_copy_int32(int swap,const int * p_odd,const int * p_even,int * buf,unsigned short width,unsigned short odd_rows,unsigned short even_rows)3659 do_copy_int32 (int swap, const int *p_odd, const int *p_even, int *buf,
3660 unsigned short width, unsigned short odd_rows,
3661 unsigned short even_rows)
3662 {
3663 /* reassembling an INT32 raster - scale 1:1 */
3664 int row;
3665 int col;
3666 int *p_out;
3667
3668 p_out = buf;
3669 for (row = 0; row < odd_rows; row++)
3670 {
3671 /* Odd scanlines */
3672 for (col = 0; col < width; col++)
3673 {
3674 if (swap)
3675 *p_out++ = swapINT32 (*p_odd++);
3676 else
3677 *p_out++ = *p_odd++;
3678 }
3679 p_out += width;
3680 }
3681
3682 p_out = buf;
3683 for (row = 0; row < even_rows; row++)
3684 {
3685 /* Even scanlines */
3686 p_out += width;
3687 for (col = 0; col < width; col++)
3688 {
3689 if (swap)
3690 *p_out++ = swapINT32 (*p_even++);
3691 else
3692 *p_out++ = *p_even++;
3693 }
3694 }
3695 }
3696
3697 static void
do_copy_uint32(int swap,const unsigned int * p_odd,const unsigned int * p_even,unsigned int * buf,unsigned short width,unsigned short odd_rows,unsigned short even_rows)3698 do_copy_uint32 (int swap, const unsigned int *p_odd, const unsigned int *p_even,
3699 unsigned int *buf, unsigned short width,
3700 unsigned short odd_rows, unsigned short even_rows)
3701 {
3702 /* reassembling an UINT32 raster - scale 1:1 */
3703 int row;
3704 int col;
3705 unsigned int *p_out;
3706
3707 p_out = buf;
3708 for (row = 0; row < odd_rows; row++)
3709 {
3710 /* Odd scanlines */
3711 for (col = 0; col < width; col++)
3712 {
3713 if (swap)
3714 *p_out++ = swapUINT32 (*p_odd++);
3715 else
3716 *p_out++ = *p_odd++;
3717 }
3718 p_out += width;
3719 }
3720
3721 p_out = buf;
3722 for (row = 0; row < even_rows; row++)
3723 {
3724 /* Even scanlines */
3725 p_out += width;
3726 for (col = 0; col < width; col++)
3727 {
3728 if (swap)
3729 *p_out++ = swapUINT32 (*p_even++);
3730 else
3731 *p_out++ = *p_even++;
3732 }
3733 }
3734 }
3735
3736 static void
do_copy_float(int swap,const float * p_odd,const float * p_even,float * buf,unsigned short width,unsigned short odd_rows,unsigned short even_rows)3737 do_copy_float (int swap, const float *p_odd, const float *p_even, float *buf,
3738 unsigned short width, unsigned short odd_rows,
3739 unsigned short even_rows)
3740 {
3741 /* reassembling a FLOAT raster - scale 1:1 */
3742 int row;
3743 int col;
3744 float *p_out;
3745
3746 p_out = buf;
3747 for (row = 0; row < odd_rows; row++)
3748 {
3749 /* Odd scanlines */
3750 for (col = 0; col < width; col++)
3751 {
3752 if (swap)
3753 *p_out++ = swapFloat (*p_odd++);
3754 else
3755 *p_out++ = *p_odd++;
3756 }
3757 p_out += width;
3758 }
3759
3760 p_out = buf;
3761 for (row = 0; row < even_rows; row++)
3762 {
3763 /* Even scanlines */
3764 p_out += width;
3765 for (col = 0; col < width; col++)
3766 {
3767 if (swap)
3768 *p_out++ = swapFloat (*p_even++);
3769 else
3770 *p_out++ = *p_even++;
3771 }
3772 }
3773 }
3774
3775 static void
do_copy_double(int swap,const double * p_odd,const double * p_even,double * buf,unsigned short width,unsigned short odd_rows,unsigned short even_rows)3776 do_copy_double (int swap, const double *p_odd, const double *p_even,
3777 double *buf, unsigned short width, unsigned short odd_rows,
3778 unsigned short even_rows)
3779 {
3780 /* reassembling a DOUBLE raster - scale 1:1 */
3781 int row;
3782 int col;
3783 double *p_out;
3784
3785 p_out = buf;
3786 for (row = 0; row < odd_rows; row++)
3787 {
3788 /* Odd scanlines */
3789 for (col = 0; col < width; col++)
3790 {
3791 if (swap)
3792 *p_out++ = swapDouble (*p_odd++);
3793 else
3794 *p_out++ = *p_odd++;
3795 }
3796 p_out += width;
3797 }
3798
3799 p_out = buf;
3800 for (row = 0; row < even_rows; row++)
3801 {
3802 /* Even scanlines */
3803 p_out += width;
3804 for (col = 0; col < width; col++)
3805 {
3806 if (swap)
3807 *p_out++ = swapDouble (*p_even++);
3808 else
3809 *p_out++ = *p_even++;
3810 }
3811 }
3812 }
3813
3814 static int
build_pixel_buffer(int swap,int scale,unsigned int * xwidth,unsigned int * xheight,unsigned char sample_type,unsigned char num_bands,unsigned short odd_rows,const void * pixels_odd,unsigned short even_rows,const void * pixels_even,void ** pixels,int * pixels_sz)3815 build_pixel_buffer (int swap, int scale, unsigned int *xwidth,
3816 unsigned int *xheight, unsigned char sample_type,
3817 unsigned char num_bands, unsigned short odd_rows,
3818 const void *pixels_odd, unsigned short even_rows,
3819 const void *pixels_even, void **pixels, int *pixels_sz)
3820 {
3821 /* decoding the raster */
3822 unsigned int width = *xwidth;
3823 unsigned int height = *xheight;
3824 void *buf;
3825 int buf_size;
3826 unsigned char pixel_size;
3827
3828 switch (sample_type)
3829 {
3830 case RL2_SAMPLE_INT16:
3831 case RL2_SAMPLE_UINT16:
3832 pixel_size = 2;
3833 break;
3834 case RL2_SAMPLE_INT32:
3835 case RL2_SAMPLE_UINT32:
3836 case RL2_SAMPLE_FLOAT:
3837 pixel_size = 4;
3838 break;
3839 case RL2_SAMPLE_DOUBLE:
3840 pixel_size = 8;
3841 break;
3842 default:
3843 pixel_size = 1;
3844 break;
3845 };
3846
3847 if (scale == RL2_SCALE_2)
3848 return build_pixel_buffer_2 (swap, xwidth, xheight, sample_type,
3849 pixel_size, num_bands, odd_rows,
3850 pixels_odd, pixels, pixels_sz);
3851 if (scale == RL2_SCALE_4)
3852 return build_pixel_buffer_4 (swap, xwidth, xheight, sample_type,
3853 pixel_size, num_bands, odd_rows,
3854 pixels_odd, pixels, pixels_sz);
3855 if (scale == RL2_SCALE_8)
3856 return build_pixel_buffer_8 (swap, xwidth, xheight, sample_type,
3857 pixel_size, num_bands, odd_rows,
3858 pixels_odd, pixels, pixels_sz);
3859
3860 buf_size = width * height * pixel_size * num_bands;
3861 buf = malloc (buf_size);
3862 if (buf == NULL)
3863 return 0;
3864
3865 switch (sample_type)
3866 {
3867 case RL2_SAMPLE_INT8:
3868 do_copy_int8 (pixels_odd, pixels_even, buf, width, odd_rows,
3869 even_rows);
3870 break;
3871 case RL2_SAMPLE_UINT8:
3872 do_copy_uint8 (pixels_odd, pixels_even, buf, width, odd_rows,
3873 even_rows, num_bands);
3874 break;
3875 case RL2_SAMPLE_INT16:
3876 do_copy_int16 (swap, pixels_odd, pixels_even, buf, width, odd_rows,
3877 even_rows);
3878 break;
3879 case RL2_SAMPLE_UINT16:
3880 do_copy_uint16 (swap, pixels_odd, pixels_even, buf, width, odd_rows,
3881 even_rows, num_bands);
3882 break;
3883 case RL2_SAMPLE_INT32:
3884 do_copy_int32 (swap, pixels_odd, pixels_even, buf, width, odd_rows,
3885 even_rows);
3886 break;
3887 case RL2_SAMPLE_UINT32:
3888 do_copy_uint32 (swap, pixels_odd, pixels_even, buf, width, odd_rows,
3889 even_rows);
3890 break;
3891 case RL2_SAMPLE_FLOAT:
3892 do_copy_float (swap, pixels_odd, pixels_even, buf, width, odd_rows,
3893 even_rows);
3894 break;
3895 case RL2_SAMPLE_DOUBLE:
3896 do_copy_double (swap, pixels_odd, pixels_even, buf, width, odd_rows,
3897 even_rows);
3898 break;
3899 };
3900
3901 *pixels = buf;
3902 *pixels_sz = buf_size;
3903 return 1;
3904 }
3905
3906 static int
rescale_mask_2(unsigned short * xwidth,unsigned short * xheight,const unsigned char * mask_pix,unsigned char ** mask,int * mask_sz)3907 rescale_mask_2 (unsigned short *xwidth, unsigned short *xheight,
3908 const unsigned char *mask_pix, unsigned char **mask,
3909 int *mask_sz)
3910 {
3911 /* rescaling a transparency mask - scale 1:2 */
3912 int row;
3913 int col;
3914 unsigned short width = *xwidth / 2.0;
3915 unsigned short height = *xheight / 2.0;
3916 unsigned char *p_out;
3917 const unsigned char *p_in = mask_pix;
3918
3919 if ((width * 2) < *xwidth)
3920 width++;
3921 if ((height * 2) < *xheight)
3922 height++;
3923 *mask_sz = width * height;
3924 *mask = malloc (*mask_sz);
3925 if (*mask == NULL)
3926 return 0;
3927 p_out = *mask;
3928
3929 for (row = 0; row < *xheight; row += 2)
3930 {
3931 for (col = 0; col < *xwidth; col += 2)
3932 {
3933 *p_out++ = *p_in++;
3934 p_in++;
3935 }
3936 p_in += *xwidth;
3937 }
3938
3939 *xwidth = width;
3940 *xheight = height;
3941 return 1;
3942 }
3943
3944 static int
rescale_mask_4(unsigned short * xwidth,unsigned short * xheight,const unsigned char * mask_pix,unsigned char ** mask,int * mask_sz)3945 rescale_mask_4 (unsigned short *xwidth, unsigned short *xheight,
3946 const unsigned char *mask_pix, unsigned char **mask,
3947 int *mask_sz)
3948 {
3949 /* rescaling a transparency mask - scale 1:4 */
3950 int row;
3951 int col;
3952 unsigned short width = *xwidth / 4.0;
3953 unsigned short height = *xheight / 4.0;
3954 unsigned char *p_out;
3955 const unsigned char *p_in = mask_pix;
3956
3957 if ((width * 4) < *xwidth)
3958 width++;
3959 if ((height * 4) < *xheight)
3960 height++;
3961 *mask_sz = width * height;
3962 *mask = malloc (*mask_sz);
3963 if (*mask == NULL)
3964 return 0;
3965 p_out = *mask;
3966
3967 for (row = 0; row < *xheight; row += 4)
3968 {
3969 for (col = 0; col < *xwidth; col += 4)
3970 {
3971 *p_out++ = *p_in++;
3972 p_in += 3;
3973 }
3974 p_in += *xwidth * 3;
3975 }
3976
3977 *xwidth = width;
3978 *xheight = height;
3979 return 1;
3980 }
3981
3982 static int
rescale_mask_8(unsigned short * xwidth,unsigned short * xheight,const unsigned char * mask_pix,unsigned char ** mask,int * mask_sz)3983 rescale_mask_8 (unsigned short *xwidth, unsigned short *xheight,
3984 const unsigned char *mask_pix, unsigned char **mask,
3985 int *mask_sz)
3986 {
3987 /* rescaling a transparency mask - scale 1:8 */
3988 int row;
3989 int col;
3990 unsigned short width = *xwidth / 8.0;
3991 unsigned short height = *xheight / 8.0;
3992 unsigned char *p_out;
3993 const unsigned char *p_in = mask_pix;
3994
3995 if ((width * 8) < *xwidth)
3996 width++;
3997 if ((height * 8) < *xheight)
3998 height++;
3999 *mask_sz = width * height;
4000 *mask = malloc (*mask_sz);
4001 if (*mask == NULL)
4002 return 0;
4003 p_out = *mask;
4004
4005 for (row = 0; row < *xheight; row += 8)
4006 {
4007 for (col = 0; col < *xwidth; col += 8)
4008 {
4009 *p_out++ = *p_in++;
4010 p_in += 7;
4011 }
4012 p_in += *xwidth * 7;
4013 }
4014
4015 *xwidth = width;
4016 *xheight = height;
4017 return 1;
4018 }
4019
4020 static int
rescale_mask(int scale,unsigned short * xwidth,unsigned short * xheight,unsigned char * mask_pix,unsigned char ** mask,int * mask_sz)4021 rescale_mask (int scale, unsigned short *xwidth, unsigned short *xheight,
4022 unsigned char *mask_pix, unsigned char **mask, int *mask_sz)
4023 {
4024 /* rescaling the transparency mask */
4025 unsigned short width = *xwidth;
4026 unsigned short height = *xheight;
4027 unsigned char *buf;
4028 int buf_size;
4029
4030 if (scale == RL2_SCALE_2)
4031 return rescale_mask_2 (xwidth, xheight, mask_pix, mask, mask_sz);
4032 if (scale == RL2_SCALE_4)
4033 return rescale_mask_4 (xwidth, xheight, mask_pix, mask, mask_sz);
4034 if (scale == RL2_SCALE_8)
4035 return rescale_mask_8 (xwidth, xheight, mask_pix, mask, mask_sz);
4036
4037 buf_size = width * height;
4038 buf = malloc (buf_size);
4039 if (buf == NULL)
4040 return 0;
4041
4042 memcpy (buf, mask_pix, buf_size);
4043 *mask = buf;
4044 *mask_sz = buf_size;
4045 return 1;
4046 }
4047
4048 static int
unpack_1bit(unsigned short width,unsigned short height,unsigned short row_stride,const unsigned char * pixels_in,unsigned char ** pixels,int * pixels_sz)4049 unpack_1bit (unsigned short width, unsigned short height,
4050 unsigned short row_stride, const unsigned char *pixels_in,
4051 unsigned char **pixels, int *pixels_sz)
4052 {
4053 /* unpacking a 1-BIT raster */
4054 unsigned char *buf;
4055 int buf_size;
4056 int row;
4057 int col;
4058 unsigned char *p_out;
4059 const unsigned char *p_in;
4060
4061 buf_size = width * height;
4062 buf = malloc (buf_size);
4063 if (buf == NULL)
4064 return 0;
4065
4066 p_in = pixels_in;
4067 p_out = buf;
4068 for (row = 0; row < height; row++)
4069 {
4070 int x = 0;
4071 for (col = 0; col < row_stride; col++)
4072 {
4073 unsigned char byte = *p_in++;
4074 if ((byte & 0x80) == 0x80)
4075 *p_out++ = 1;
4076 else
4077 *p_out++ = 0;
4078 x++;
4079 if (x >= width)
4080 break;
4081 if ((byte & 0x40) == 0x40)
4082 *p_out++ = 1;
4083 else
4084 *p_out++ = 0;
4085 x++;
4086 if (x >= width)
4087 break;
4088 if ((byte & 0x20) == 0x20)
4089 *p_out++ = 1;
4090 else
4091 *p_out++ = 0;
4092 x++;
4093 if (x >= width)
4094 break;
4095 if ((byte & 0x10) == 0x10)
4096 *p_out++ = 1;
4097 else
4098 *p_out++ = 0;
4099 x++;
4100 if (x >= width)
4101 break;
4102 if ((byte & 0x08) == 0x08)
4103 *p_out++ = 1;
4104 else
4105 *p_out++ = 0;
4106 if ((byte & 0x04) == 0x04)
4107 *p_out++ = 1;
4108 else
4109 *p_out++ = 0;
4110 x++;
4111 if (x >= width)
4112 break;
4113 if ((byte & 0x02) == 0x02)
4114 *p_out++ = 1;
4115 else
4116 *p_out++ = 0;
4117 x++;
4118 if (x >= width)
4119 break;
4120 if ((byte & 0x01) == 0x01)
4121 *p_out++ = 1;
4122 else
4123 *p_out++ = 0;
4124 }
4125 }
4126
4127 *pixels = buf;
4128 *pixels_sz = buf_size;
4129 return 1;
4130 }
4131
4132 static int
unpack_2bit(unsigned short width,unsigned short height,unsigned short row_stride,const unsigned char * pixels_in,unsigned char ** pixels,int * pixels_sz)4133 unpack_2bit (unsigned short width, unsigned short height,
4134 unsigned short row_stride, const unsigned char *pixels_in,
4135 unsigned char **pixels, int *pixels_sz)
4136 {
4137 /* unpacking a 2-BIT raster */
4138 void *buf;
4139 int buf_size;
4140 int row;
4141 int col;
4142 unsigned char *p_out;
4143 const unsigned char *p_in;
4144
4145 buf_size = width * height;
4146 buf = malloc (buf_size);
4147 if (buf == NULL)
4148 return 0;
4149
4150 p_in = pixels_in;
4151 p_out = buf;
4152 for (row = 0; row < height; row++)
4153 {
4154 int x = 0;
4155 for (col = 0; col < row_stride; col++)
4156 {
4157 unsigned char byte = *p_in++;
4158 unsigned char hi0 = byte & 0xc0;
4159 unsigned char hi1 = byte & 0x30;
4160 unsigned char lo0 = byte & 0x0c;
4161 unsigned char lo1 = byte & 0x03;
4162 switch (hi0)
4163 {
4164 case 0x00:
4165 *p_out++ = 0;
4166 break;
4167 case 0x40:
4168 *p_out++ = 1;
4169 break;
4170 case 0x80:
4171 *p_out++ = 2;
4172 break;
4173 case 0xc0:
4174 *p_out++ = 3;
4175 break;
4176 };
4177 x++;
4178 if (x >= width)
4179 break;
4180 switch (hi1)
4181 {
4182 case 0x00:
4183 *p_out++ = 0;
4184 break;
4185 case 0x10:
4186 *p_out++ = 1;
4187 break;
4188 case 0x20:
4189 *p_out++ = 2;
4190 break;
4191 case 0x30:
4192 *p_out++ = 3;
4193 break;
4194 };
4195 x++;
4196 if (x >= width)
4197 break;
4198 switch (lo0)
4199 {
4200 case 0x00:
4201 *p_out++ = 0;
4202 break;
4203 case 0x04:
4204 *p_out++ = 1;
4205 break;
4206 case 0x08:
4207 *p_out++ = 2;
4208 break;
4209 case 0x0c:
4210 *p_out++ = 3;
4211 break;
4212 };
4213 x++;
4214 if (x >= width)
4215 break;
4216 switch (lo1)
4217 {
4218 case 0x00:
4219 *p_out++ = 0;
4220 break;
4221 case 0x01:
4222 *p_out++ = 1;
4223 break;
4224 case 0x02:
4225 *p_out++ = 2;
4226 break;
4227 case 0x03:
4228 *p_out++ = 3;
4229 break;
4230 };
4231 x++;
4232 }
4233 }
4234
4235 *pixels = buf;
4236 *pixels_sz = buf_size;
4237 return 1;
4238 }
4239
4240 static int
unpack_4bit(unsigned short width,unsigned short height,unsigned short row_stride,const unsigned char * pixels_in,unsigned char ** pixels,int * pixels_sz)4241 unpack_4bit (unsigned short width, unsigned short height,
4242 unsigned short row_stride, const unsigned char *pixels_in,
4243 unsigned char **pixels, int *pixels_sz)
4244 {
4245 /* unpacking a 4-BIT raster */
4246 void *buf;
4247 int buf_size;
4248 int row;
4249 int col;
4250 unsigned char *p_out;
4251 const unsigned char *p_in;
4252
4253 buf_size = width * height;
4254 buf = malloc (buf_size);
4255 if (buf == NULL)
4256 return 0;
4257
4258 p_in = pixels_in;
4259 p_out = buf;
4260 for (row = 0; row < height; row++)
4261 {
4262 int x = 0;
4263 for (col = 0; col < row_stride; col++)
4264 {
4265 unsigned char byte = *p_in++;
4266 unsigned char hi = byte & 0xf0;
4267 unsigned char lo = byte & 0x0f;
4268 switch (hi)
4269 {
4270 case 0x00:
4271 *p_out++ = 0;
4272 break;
4273 case 0x10:
4274 *p_out++ = 1;
4275 break;
4276 case 0x20:
4277 *p_out++ = 2;
4278 break;
4279 case 0x30:
4280 *p_out++ = 3;
4281 break;
4282 case 0x40:
4283 *p_out++ = 4;
4284 break;
4285 case 0x50:
4286 *p_out++ = 5;
4287 break;
4288 case 0x60:
4289 *p_out++ = 6;
4290 break;
4291 case 0x70:
4292 *p_out++ = 7;
4293 break;
4294 case 0x80:
4295 *p_out++ = 8;
4296 break;
4297 case 0x90:
4298 *p_out++ = 9;
4299 break;
4300 case 0xa0:
4301 *p_out++ = 10;
4302 break;
4303 case 0xb0:
4304 *p_out++ = 11;
4305 break;
4306 case 0xc0:
4307 *p_out++ = 12;
4308 break;
4309 case 0xd0:
4310 *p_out++ = 13;
4311 break;
4312 case 0xe0:
4313 *p_out++ = 14;
4314 break;
4315 case 0xf0:
4316 *p_out++ = 15;
4317 break;
4318 };
4319 x++;
4320 if (x >= width)
4321 break;
4322 switch (lo)
4323 {
4324 case 0x00:
4325 *p_out++ = 0;
4326 break;
4327 case 0x01:
4328 *p_out++ = 1;
4329 break;
4330 case 0x02:
4331 *p_out++ = 2;
4332 break;
4333 case 0x03:
4334 *p_out++ = 3;
4335 break;
4336 case 0x04:
4337 *p_out++ = 4;
4338 break;
4339 case 0x05:
4340 *p_out++ = 5;
4341 break;
4342 case 0x06:
4343 *p_out++ = 6;
4344 break;
4345 case 0x07:
4346 *p_out++ = 7;
4347 break;
4348 case 0x08:
4349 *p_out++ = 8;
4350 break;
4351 case 0x09:
4352 *p_out++ = 9;
4353 break;
4354 case 0x0a:
4355 *p_out++ = 10;
4356 break;
4357 case 0x0b:
4358 *p_out++ = 11;
4359 break;
4360 case 0x0c:
4361 *p_out++ = 12;
4362 break;
4363 case 0x0d:
4364 *p_out++ = 13;
4365 break;
4366 case 0x0e:
4367 *p_out++ = 14;
4368 break;
4369 case 0x0f:
4370 *p_out++ = 15;
4371 break;
4372 };
4373 x++;
4374 }
4375 }
4376
4377 *pixels = buf;
4378 *pixels_sz = buf_size;
4379 return 1;
4380 }
4381
4382 RL2_DECLARE int
rl2_is_valid_dbms_raster_tile(unsigned short level,unsigned int tile_width,unsigned int tile_height,const unsigned char * blob_odd,int blob_odd_sz,const unsigned char * blob_even,int blob_even_sz,unsigned char sample_type,unsigned char pixel_type,unsigned char num_bands,unsigned char compression)4383 rl2_is_valid_dbms_raster_tile (unsigned short level, unsigned int tile_width,
4384 unsigned int tile_height,
4385 const unsigned char *blob_odd, int blob_odd_sz,
4386 const unsigned char *blob_even, int blob_even_sz,
4387 unsigned char sample_type,
4388 unsigned char pixel_type,
4389 unsigned char num_bands,
4390 unsigned char compression)
4391 {
4392 /* testing a serialized Raster Tile object for validity */
4393 unsigned int width;
4394 unsigned int height;
4395 unsigned char xsample_type;
4396 unsigned char xpixel_type;
4397 unsigned char xnum_bands;
4398 unsigned char xcompression;
4399 uLong crc;
4400 if (!check_blob_odd
4401 (blob_odd, blob_odd_sz, &width, &height, &xsample_type, &xpixel_type,
4402 &xnum_bands, &xcompression, &crc))
4403 return RL2_ERROR;
4404 if (blob_even != NULL)
4405 {
4406 if (!check_blob_even
4407 (blob_even, blob_even_sz, width, height, xsample_type,
4408 xpixel_type, xnum_bands, xcompression, crc))
4409 return RL2_ERROR;
4410 }
4411 if (width != tile_width || height != tile_height)
4412 return RL2_ERROR;
4413 if (level == 0)
4414 {
4415 /* base-level tile */
4416 if (sample_type == xsample_type && pixel_type == xpixel_type
4417 && num_bands == xnum_bands && compression == xcompression)
4418 return RL2_OK;
4419 }
4420 else
4421 {
4422 /* Pyramid-level tile */
4423 if (sample_type == RL2_SAMPLE_UINT8 && pixel_type == RL2_PIXEL_RGB
4424 && num_bands == 3)
4425 {
4426 /* expecting an RGB/JPEG Pyramid tile 8bit */
4427 if (xsample_type == RL2_SAMPLE_UINT8
4428 && xpixel_type == RL2_PIXEL_RGB && xnum_bands == 3
4429 && xcompression == RL2_COMPRESSION_JPEG)
4430 return RL2_OK;
4431 }
4432 if (sample_type == RL2_SAMPLE_UINT8
4433 && pixel_type == RL2_PIXEL_GRAYSCALE && num_bands == 1)
4434 {
4435 /* expecting a GRAYSCALE/JPEG Pyramid tile 8bit */
4436 if (xsample_type == RL2_SAMPLE_UINT8
4437 && xpixel_type == RL2_PIXEL_GRAYSCALE && xnum_bands == 1
4438 && xcompression == RL2_COMPRESSION_JPEG)
4439 return RL2_OK;
4440 }
4441 if (sample_type == RL2_SAMPLE_UINT16 && pixel_type == RL2_PIXEL_RGB
4442 && num_bands == 3)
4443 {
4444 /* expecting an RGB/JPEG Pyramid tile 16bit */
4445 if (xsample_type == RL2_SAMPLE_UINT16
4446 && xpixel_type == RL2_PIXEL_RGB && xnum_bands == 3
4447 && xcompression == RL2_COMPRESSION_DEFLATE)
4448 return RL2_OK;
4449 }
4450 if (sample_type == RL2_SAMPLE_UINT16
4451 && pixel_type == RL2_PIXEL_GRAYSCALE && num_bands == 1)
4452 {
4453 /* expecting a GRAYSCALE/JPEG Pyramid tile 16bit */
4454 if (xsample_type == RL2_SAMPLE_UINT16
4455 && xpixel_type == RL2_PIXEL_GRAYSCALE && xnum_bands == 1
4456 && xcompression == RL2_COMPRESSION_DEFLATE)
4457 return RL2_OK;
4458 }
4459 if (sample_type == RL2_SAMPLE_1_BIT
4460 && pixel_type == RL2_PIXEL_MONOCHROME && num_bands == 1)
4461 {
4462 /* expecting a GRAYSCALE/PNG Pyramid tile */
4463 if (xsample_type == RL2_SAMPLE_UINT8
4464 && xpixel_type == RL2_PIXEL_GRAYSCALE && xnum_bands == 1
4465 && xcompression == RL2_COMPRESSION_PNG)
4466 return RL2_OK;
4467 }
4468 if ((sample_type == RL2_SAMPLE_1_BIT
4469 && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1) ||
4470 (sample_type == RL2_SAMPLE_2_BIT
4471 && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1) ||
4472 (sample_type == RL2_SAMPLE_4_BIT
4473 && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1))
4474 {
4475 /* expecting an RGB/PNG Pyramid tile */
4476 if (xsample_type == RL2_SAMPLE_UINT8
4477 && xpixel_type == RL2_PIXEL_RGB && xnum_bands == 3
4478 && xcompression == RL2_COMPRESSION_PNG)
4479 return RL2_OK;
4480 }
4481 if (sample_type == RL2_SAMPLE_UINT8 && pixel_type == RL2_PIXEL_PALETTE
4482 && num_bands == 1)
4483 {
4484 /* expecting an RGB/JPEG Pyramid tile */
4485 if (xsample_type == RL2_SAMPLE_UINT8
4486 && xpixel_type == RL2_PIXEL_RGB && xnum_bands == 3
4487 && xcompression == RL2_COMPRESSION_JPEG)
4488 return RL2_OK;
4489 }
4490 if (sample_type == xsample_type && pixel_type == RL2_PIXEL_DATAGRID
4491 && num_bands == xnum_bands
4492 && xcompression == RL2_COMPRESSION_DEFLATE)
4493 return RL2_OK;
4494 if (sample_type == xsample_type && pixel_type == RL2_PIXEL_MULTIBAND
4495 && num_bands == xnum_bands
4496 && xcompression == RL2_COMPRESSION_DEFLATE)
4497 return RL2_OK;
4498 }
4499 return RL2_ERROR;
4500 }
4501
4502 RL2_DECLARE rl2RasterPtr
rl2_raster_decode(int scale,const unsigned char * blob_odd,int blob_odd_sz,const unsigned char * blob_even,int blob_even_sz,rl2PalettePtr ext_palette)4503 rl2_raster_decode (int scale, const unsigned char *blob_odd,
4504 int blob_odd_sz, const unsigned char *blob_even,
4505 int blob_even_sz, rl2PalettePtr ext_palette)
4506 {
4507 /* decoding from internal RL2 binary format to Raster */
4508 rl2RasterPtr raster;
4509 rl2PalettePtr palette = NULL;
4510 rl2PalettePtr palette2 = NULL;
4511 unsigned int width;
4512 unsigned int height;
4513 unsigned short mask_width;
4514 unsigned short mask_height;
4515 unsigned char sample_type;
4516 unsigned char pixel_type;
4517 unsigned char num_bands;
4518 unsigned char compression;
4519 unsigned short row_stride_odd;
4520 unsigned int odd_rows;
4521 unsigned int even_rows;
4522 int uncompressed_odd;
4523 int compressed_odd;
4524 int uncompressed_mask;
4525 int compressed_mask;
4526 int uncompressed_even = 0;
4527 int compressed_even = 0;
4528 uLong crc;
4529 const unsigned char *pixels_odd;
4530 const unsigned char *pixels_even;
4531 const unsigned char *pixels_mask = NULL;
4532 unsigned char *pixels = NULL;
4533 int pixels_sz;
4534 unsigned char *mask = NULL;
4535 int mask_sz = 0;
4536 const unsigned char *ptr;
4537 unsigned char *odd_data = NULL;
4538 unsigned char *even_data = NULL;
4539 unsigned char *odd_mask = NULL;
4540 unsigned char *even_mask = NULL;
4541 int odd_mask_sz;
4542 int even_mask_sz;
4543 int swap;
4544 int endian;
4545 int endian_arch = endianArch ();
4546 if (blob_odd == NULL)
4547 return NULL;
4548 if (!check_blob_odd
4549 (blob_odd, blob_odd_sz, &width, &height, &sample_type, &pixel_type,
4550 &num_bands, &compression, &crc))
4551 return NULL;
4552 if (blob_even != NULL)
4553 {
4554 if (!check_blob_even
4555 (blob_even, blob_even_sz, width, height, sample_type, pixel_type,
4556 num_bands, compression, crc))
4557 return NULL;
4558 }
4559 if (!check_scale (scale, sample_type, compression, blob_even))
4560 return NULL;
4561
4562 endian = *(blob_odd + 2);
4563 num_bands = *(blob_odd + 6);
4564 ptr = blob_odd + 11;
4565 row_stride_odd = importU16 (ptr, endian, endian_arch);
4566 ptr += 2;
4567 odd_rows = importU16 (ptr, endian, endian_arch);
4568 ptr += 2;
4569 uncompressed_odd = importU32 (ptr, endian, endian_arch);
4570 ptr += 4;
4571 compressed_odd = importU32 (ptr, endian, endian_arch);
4572 ptr += 4;
4573 uncompressed_mask = importU32 (ptr, endian, endian_arch);
4574 ptr += 4;
4575 compressed_mask = importU32 (ptr, endian, endian_arch);
4576 ptr += 4;
4577 if (*ptr++ != RL2_DATA_START)
4578 return NULL;
4579 pixels_odd = ptr;
4580 if (uncompressed_mask > 0)
4581 {
4582 /* retrieving the mask */
4583 ptr += compressed_odd;
4584 if (*ptr++ != RL2_DATA_END)
4585 return NULL;
4586 if (*ptr++ != RL2_MASK_START)
4587 return NULL;
4588 pixels_mask = ptr;
4589 mask_width = width;
4590 mask_height = height;
4591 ptr += compressed_mask;
4592 if (*ptr++ != RL2_MASK_END)
4593 return NULL;
4594 }
4595 if (blob_even != NULL)
4596 {
4597 ptr = blob_even + 11;
4598 even_rows = importU16 (ptr, endian, endian_arch);
4599 ptr += 2;
4600 ptr += 4; /* skipping OddBlock CRC */
4601 uncompressed_even = importU32 (ptr, endian, endian_arch);
4602 ptr += 4;
4603 compressed_even = importU32 (ptr, endian, endian_arch);
4604 ptr += 4;
4605 if (*ptr++ != RL2_DATA_START)
4606 return NULL;
4607 pixels_even = ptr;
4608 }
4609 else
4610 {
4611 compressed_even = 0;
4612 uncompressed_even = 0;
4613 pixels_even = NULL;
4614 }
4615
4616 if (compression == RL2_COMPRESSION_DEFLATE
4617 && uncompressed_odd != compressed_odd)
4618 {
4619 /* decompressing from ZIP [Deflate] - ODD Block */
4620 uLong refLen = uncompressed_odd;
4621 const Bytef *in = pixels_odd;
4622 odd_data = malloc (uncompressed_odd);
4623 if (odd_data == NULL)
4624 goto error;
4625 if (uncompress (odd_data, &refLen, in, compressed_odd) != Z_OK)
4626 goto error;
4627 pixels_odd = odd_data;
4628 if (pixels_even != NULL && uncompressed_even != compressed_even)
4629 {
4630 /* decompressing from ZIP [Deflate] - EVEN Block */
4631 uLong refLen = uncompressed_even;
4632 const Bytef *in = pixels_even;
4633 even_data = malloc (uncompressed_even);
4634 if (even_data == NULL)
4635 goto error;
4636 if (uncompress (even_data, &refLen, in, compressed_even) !=
4637 Z_OK)
4638 goto error;
4639 pixels_even = even_data;
4640 }
4641 }
4642 if (compression == RL2_COMPRESSION_LZMA
4643 && uncompressed_odd != compressed_odd)
4644 {
4645 /* decompressing from LZMA - ODD Block */
4646 lzma_options_lzma opt_lzma2;
4647 lzma_filter filters[2];
4648 size_t in_pos = 0;
4649 size_t out_pos = 0;
4650 size_t refLen = compressed_odd;
4651 odd_data = malloc (uncompressed_odd);
4652 if (odd_data == NULL)
4653 goto error;
4654 lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
4655 filters[0].id = LZMA_FILTER_LZMA2;
4656 filters[0].options = &opt_lzma2;
4657 filters[1].id = LZMA_VLI_UNKNOWN;
4658 filters[1].options = NULL;
4659 if (lzma_raw_buffer_decode
4660 (filters, NULL, pixels_odd, &in_pos, refLen, odd_data, &out_pos,
4661 uncompressed_odd) != LZMA_OK)
4662 goto error;
4663 pixels_odd = odd_data;
4664 if (pixels_even != NULL && uncompressed_even != compressed_even)
4665 {
4666 /* decompressing from LZMA - EVEN Block */
4667 lzma_options_lzma opt_lzma2;
4668 lzma_filter filters[2];
4669 size_t in_pos = 0;
4670 size_t out_pos = 0;
4671 size_t refLen = compressed_even;
4672 even_data = malloc (uncompressed_even);
4673 if (even_data == NULL)
4674 goto error;
4675 lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
4676 filters[0].id = LZMA_FILTER_LZMA2;
4677 filters[0].options = &opt_lzma2;
4678 filters[1].id = LZMA_VLI_UNKNOWN;
4679 filters[1].options = NULL;
4680 if (lzma_raw_buffer_decode
4681 (filters, NULL, pixels_even, &in_pos, refLen, even_data,
4682 &out_pos, uncompressed_even) != LZMA_OK)
4683 goto error;
4684 pixels_even = even_data;
4685 }
4686 }
4687 if (compression == RL2_COMPRESSION_JPEG)
4688 {
4689 /* decompressing from JPEG - always on the ODD Block */
4690 int ret = RL2_ERROR;
4691 unsigned char pix_typ;
4692 switch (scale)
4693 {
4694 case RL2_SCALE_1:
4695 ret =
4696 rl2_decode_jpeg_scaled (1, pixels_odd, compressed_odd,
4697 &width, &height, &pix_typ, &pixels,
4698 &pixels_sz);
4699 break;
4700 case RL2_SCALE_2:
4701 ret =
4702 rl2_decode_jpeg_scaled (2, pixels_odd, compressed_odd,
4703 &width, &height, &pix_typ, &pixels,
4704 &pixels_sz);
4705 break;
4706 case RL2_SCALE_4:
4707 ret =
4708 rl2_decode_jpeg_scaled (4, pixels_odd, compressed_odd,
4709 &width, &height, &pix_typ, &pixels,
4710 &pixels_sz);
4711 break;
4712 case RL2_SCALE_8:
4713 ret =
4714 rl2_decode_jpeg_scaled (8, pixels_odd, compressed_odd,
4715 &width, &height, &pix_typ, &pixels,
4716 &pixels_sz);
4717 break;
4718 };
4719 if (ret != RL2_OK)
4720 goto error;
4721 goto done;
4722 }
4723 if (compression == RL2_COMPRESSION_LOSSY_WEBP
4724 || compression == RL2_COMPRESSION_LOSSLESS_WEBP)
4725 {
4726 /* decompressing from WEBP - always on the ODD Block */
4727 int ret = RL2_ERROR;
4728 switch (scale)
4729 {
4730 case RL2_SCALE_1:
4731 ret =
4732 rl2_decode_webp_scaled (1, pixels_odd, compressed_odd,
4733 &width, &height, pixel_type,
4734 &pixels, &pixels_sz, &mask,
4735 &mask_sz);
4736 break;
4737 case RL2_SCALE_2:
4738 ret =
4739 rl2_decode_webp_scaled (2, pixels_odd, compressed_odd,
4740 &width, &height, pixel_type,
4741 &pixels, &pixels_sz, &mask,
4742 &mask_sz);
4743 break;
4744 case RL2_SCALE_4:
4745 ret =
4746 rl2_decode_webp_scaled (4, pixels_odd, compressed_odd,
4747 &width, &height, pixel_type,
4748 &pixels, &pixels_sz, &mask,
4749 &mask_sz);
4750 break;
4751 case RL2_SCALE_8:
4752 ret =
4753 rl2_decode_webp_scaled (8, pixels_odd, compressed_odd,
4754 &width, &height, pixel_type,
4755 &pixels, &pixels_sz, &mask,
4756 &mask_sz);
4757 break;
4758 };
4759 if (ret != RL2_OK)
4760 goto error;
4761 goto done;
4762 }
4763 if (compression == RL2_COMPRESSION_PNG)
4764 {
4765 /* decompressing from PNG */
4766 int ret;
4767 if (sample_type == RL2_SAMPLE_1_BIT || sample_type == RL2_SAMPLE_2_BIT
4768 || sample_type == RL2_SAMPLE_4_BIT)
4769 {
4770 /* Palette or Grayscale - 1,2 or 4 bit isn't scalable */
4771 if (scale != RL2_SCALE_1)
4772 goto error;
4773 ret =
4774 rl2_decode_png (pixels_odd, compressed_odd,
4775 &width, &height, &sample_type, &pixel_type,
4776 &num_bands, &pixels, &pixels_sz, &mask,
4777 &mask_sz, &palette);
4778 if (ret != RL2_OK)
4779 goto error;
4780 goto done;
4781 }
4782 else
4783 {
4784 ret = rl2_decode_png (pixels_odd, compressed_odd,
4785 &width, &odd_rows, &sample_type,
4786 &pixel_type, &num_bands, &odd_data,
4787 &pixels_sz, &odd_mask, &odd_mask_sz,
4788 &palette);
4789 if (ret != RL2_OK)
4790 goto error;
4791 pixels_odd = odd_data;
4792 if (scale == RL2_SCALE_1)
4793 {
4794 ret = rl2_decode_png (pixels_even, compressed_even,
4795 &width, &even_rows, &sample_type,
4796 &pixel_type, &num_bands, &even_data,
4797 &pixels_sz, &even_mask,
4798 &even_mask_sz, &palette2);
4799 if (ret != RL2_OK)
4800 goto error;
4801 rl2_destroy_palette (palette2);
4802 }
4803 pixels_even = even_data;
4804 if (odd_mask != NULL)
4805 free (odd_mask);
4806 if (even_mask != NULL)
4807 free (even_mask);
4808 goto merge;
4809 }
4810 }
4811 if (compression == RL2_COMPRESSION_CCITTFAX4)
4812 {
4813 /* decompressing from TIFF FAX4 */
4814 int ret;
4815 if (sample_type == RL2_SAMPLE_1_BIT && scale == RL2_SCALE_1)
4816 ;
4817 else
4818 goto error;
4819 ret =
4820 rl2_decode_tiff_mono4 (pixels_odd, compressed_odd,
4821 &width, &height, &pixels, &pixels_sz);
4822 if (ret != RL2_OK)
4823 goto error;
4824 sample_type = RL2_SAMPLE_1_BIT;
4825 pixel_type = RL2_PIXEL_MONOCHROME;
4826 num_bands = 1;
4827 goto done;
4828 }
4829
4830 if (sample_type == RL2_SAMPLE_1_BIT)
4831 {
4832 if (!unpack_1bit
4833 (width, height, row_stride_odd, pixels_odd, &pixels, &pixels_sz))
4834 goto error;
4835 }
4836 else if (sample_type == RL2_SAMPLE_2_BIT)
4837 {
4838 if (!unpack_2bit
4839 (width, height, row_stride_odd, pixels_odd, &pixels, &pixels_sz))
4840 goto error;
4841 }
4842 else if (sample_type == RL2_SAMPLE_4_BIT)
4843 {
4844 if (!unpack_4bit
4845 (width, height, row_stride_odd, pixels_odd, &pixels, &pixels_sz))
4846 goto error;
4847 }
4848 else
4849 {
4850 merge:
4851 if (endian != endian_arch)
4852 swap = 1;
4853 else
4854 swap = 0;
4855 if (!build_pixel_buffer
4856 (swap, scale, &width, &height, sample_type, num_bands, odd_rows,
4857 pixels_odd, even_rows, pixels_even, (void **) (&pixels),
4858 &pixels_sz))
4859 goto error;
4860 }
4861
4862 done:
4863 if (pixels_mask != NULL)
4864 {
4865 /* unpacking the mask */
4866 unsigned char *mask_pix;
4867 int mask_pix_sz;
4868 if (uncompressed_mask != (mask_width * mask_height))
4869 goto error;
4870 if (!unpack_rle
4871 (mask_width, mask_height, pixels_mask, compressed_mask, &mask_pix,
4872 &mask_pix_sz))
4873 goto error;
4874 if (!rescale_mask
4875 (scale, &mask_width, &mask_height, mask_pix, &mask, &mask_sz))
4876 {
4877 free (mask_pix);
4878 goto error;
4879 }
4880 free (mask_pix);
4881 }
4882
4883 if (palette == NULL)
4884 {
4885 palette = ext_palette;
4886 ext_palette = NULL;
4887 }
4888 else
4889 {
4890 if (ext_palette != NULL)
4891 rl2_destroy_palette (ext_palette);
4892 }
4893 raster =
4894 rl2_create_raster (width, height, sample_type, pixel_type, num_bands,
4895 pixels, pixels_sz, palette, mask, mask_sz, NULL);
4896 if (raster == NULL)
4897 goto error;
4898 if (odd_data != NULL)
4899 free (odd_data);
4900 if (even_data != NULL)
4901 free (even_data);
4902 return raster;
4903 error:
4904 if (odd_mask != NULL)
4905 free (odd_mask);
4906 if (even_mask != NULL)
4907 free (even_mask);
4908 if (odd_data != NULL)
4909 free (odd_data);
4910 if (even_data != NULL)
4911 free (even_data);
4912 if (pixels != NULL)
4913 free (pixels);
4914 if (mask != NULL)
4915 free (mask);
4916 if (palette != NULL)
4917 rl2_destroy_palette (palette);
4918 if (ext_palette != NULL)
4919 rl2_destroy_palette (ext_palette);
4920 return NULL;
4921 }
4922
4923 static void
add_pooled_variance(rl2PrivBandStatisticsPtr band_in,rl2PrivBandStatisticsPtr band_out,double count)4924 add_pooled_variance (rl2PrivBandStatisticsPtr band_in,
4925 rl2PrivBandStatisticsPtr band_out, double count)
4926 {
4927 /* adding a Pooled Variance item */
4928 rl2PoolVariancePtr pool = malloc (sizeof (rl2PoolVariance));
4929 pool->count = count;
4930 pool->variance = band_in->sum_sq_diff / (count - 1.0);
4931 pool->next = NULL;
4932 if (band_out->first == NULL)
4933 band_out->first = pool;
4934 if (band_out->last != NULL)
4935 band_out->last->next = pool;
4936 band_out->last = pool;
4937 }
4938
4939 static void
do_aggregate_histograms(rl2PrivBandStatisticsPtr band_in,rl2PrivBandStatisticsPtr band_out)4940 do_aggregate_histograms (rl2PrivBandStatisticsPtr band_in,
4941 rl2PrivBandStatisticsPtr band_out)
4942 {
4943 /* rescaling and aggregating histograms */
4944 int ih;
4945 double interval_in = band_in->max - band_in->min;
4946 double interval_out = band_out->max - band_out->min;
4947 double step_in = interval_in / ((double) (band_in->nHistogram) - 1.0);
4948 double step_out = interval_out / ((double) (band_out->nHistogram) - 1.0);
4949 for (ih = 0; ih < band_in->nHistogram; ih++)
4950 {
4951 double value = (((double) ih + 0.5) * step_in) + band_in->min;
4952 double qty = *(band_in->histogram + ih);
4953 double index = floor ((value - band_out->min) / step_out);
4954 if (index < 0.0)
4955 index = 0.0;
4956 if (index > 255.0)
4957 index = 255.0;
4958 *(band_out->histogram + (unsigned int) index) += qty;
4959 }
4960 }
4961
4962 RL2_DECLARE int
rl2_aggregate_raster_statistics(rl2RasterStatisticsPtr stats_in,rl2RasterStatisticsPtr stats_out)4963 rl2_aggregate_raster_statistics (rl2RasterStatisticsPtr stats_in,
4964 rl2RasterStatisticsPtr stats_out)
4965 {
4966 /* aggregating Raster Statistics */
4967 rl2PrivRasterStatisticsPtr in = (rl2PrivRasterStatisticsPtr) stats_in;
4968 rl2PrivRasterStatisticsPtr out = (rl2PrivRasterStatisticsPtr) stats_out;
4969 rl2PrivBandStatisticsPtr band_in;
4970 rl2PrivBandStatisticsPtr band_out;
4971 int ib;
4972 int ih;
4973
4974 if (in == NULL || out == NULL)
4975 return RL2_ERROR;
4976 if (in->sampleType != out->sampleType)
4977 return RL2_ERROR;
4978 if (in->nBands != out->nBands)
4979 return RL2_ERROR;
4980
4981 if (out->count == 0.0)
4982 {
4983 /* initializing */
4984 out->no_data = in->no_data;
4985 out->count = in->count;
4986 for (ib = 0; ib < in->nBands; ib++)
4987 {
4988 band_in = in->band_stats + ib;
4989 band_out = out->band_stats + ib;
4990 band_out->min = band_in->min;
4991 band_out->max = band_in->max;
4992 band_out->mean = band_in->mean;
4993 add_pooled_variance (band_in, band_out, in->count);
4994 for (ih = 0; ih < band_in->nHistogram; ih++)
4995 *(band_out->histogram + ih) = *(band_in->histogram + ih);
4996 }
4997 }
4998 else
4999 {
5000 /* aggregating */
5001 out->no_data += in->no_data;
5002 for (ib = 0; ib < in->nBands; ib++)
5003 {
5004 band_in = in->band_stats + ib;
5005 band_out = out->band_stats + ib;
5006 if (band_in->min < band_out->min)
5007 band_out->min = band_in->min;
5008 if (band_in->max > band_out->max)
5009 band_out->max = band_in->max;
5010 add_pooled_variance (band_in, band_out, in->count);
5011 band_out->mean =
5012 ((band_out->mean * out->count) +
5013 (band_in->mean * in->count)) / (out->count + in->count);
5014 if (out->sampleType == RL2_SAMPLE_INT8
5015 || out->sampleType == RL2_SAMPLE_UINT8)
5016 {
5017 /* just copying 8-bit histograms */
5018 for (ih = 0; ih < band_in->nHistogram; ih++)
5019 *(band_out->histogram + ih) +=
5020 *(band_in->histogram + ih);
5021 }
5022 else
5023 {
5024 /* rescaling and aggregating histograms */
5025 do_aggregate_histograms (band_in, band_out);
5026 }
5027 }
5028 out->count += in->count;
5029 }
5030 return RL2_OK;
5031 }
5032
5033 static void
update_no_data_stats(rl2PrivRasterStatisticsPtr st)5034 update_no_data_stats (rl2PrivRasterStatisticsPtr st)
5035 {
5036 /* updating the NoData count */
5037 st->no_data += 1.0;
5038 }
5039
5040 static void
update_count_stats(rl2PrivRasterStatisticsPtr st)5041 update_count_stats (rl2PrivRasterStatisticsPtr st)
5042 {
5043 /* updating the samples count */
5044 st->count += 1.0;
5045 }
5046
5047 static void
update_stats(rl2PrivRasterStatisticsPtr st,int band,double value)5048 update_stats (rl2PrivRasterStatisticsPtr st, int band, double value)
5049 {
5050 /* updating the Statistics */
5051 rl2PrivBandStatisticsPtr band_st = st->band_stats + band;
5052 if (value < band_st->min)
5053 band_st->min = value;
5054 if (value > band_st->max)
5055 band_st->max = value;
5056 if (st->count == 0.0)
5057 {
5058 band_st->mean = value;
5059 band_st->sum_sq_diff = 0.0;
5060 }
5061 else
5062 {
5063 band_st->sum_sq_diff =
5064 band_st->sum_sq_diff +
5065 (((st->count -
5066 1.0) * ((value - band_st->mean) * (value -
5067 band_st->mean))) /
5068 st->count);
5069 band_st->mean = band_st->mean + ((value - band_st->mean) / st->count);
5070 }
5071 if (st->sampleType == RL2_SAMPLE_INT8)
5072 {
5073 int idx = value + 128;
5074 *(band_st->histogram + idx) += 1.0;
5075 }
5076 else if (st->sampleType == RL2_SAMPLE_1_BIT
5077 || st->sampleType == RL2_SAMPLE_2_BIT
5078 || st->sampleType == RL2_SAMPLE_4_BIT
5079 || st->sampleType == RL2_SAMPLE_UINT8)
5080 {
5081 int idx = value;
5082 *(band_st->histogram + idx) += 1.0;
5083 }
5084 }
5085
5086 static void
update_int8_stats(unsigned short width,unsigned short height,const char * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5087 update_int8_stats (unsigned short width, unsigned short height,
5088 const char *pixels, const unsigned char *mask,
5089 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5090 {
5091 /* computing INT8 tile statistics */
5092 int x;
5093 int y;
5094 const char *p_in = pixels;
5095 const unsigned char *p_msk = mask;
5096 int transparent;
5097 unsigned char sample_type;
5098 unsigned char pixel_type;
5099 unsigned char nbands;
5100 int ignore_no_data = 1;
5101
5102 if (no_data != NULL)
5103 {
5104 ignore_no_data = 0;
5105 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5106 != RL2_OK)
5107 ignore_no_data = 1;
5108 if (nbands != 1)
5109 ignore_no_data = 1;
5110 if (sample_type == RL2_SAMPLE_INT8)
5111 ;
5112 else
5113 ignore_no_data = 1;
5114 }
5115
5116 for (y = 0; y < height; y++)
5117 {
5118 for (x = 0; x < width; x++)
5119 {
5120 transparent = 0;
5121 if (p_msk != NULL)
5122 {
5123 if (*p_msk++ == 0)
5124 transparent = 1;
5125 }
5126 if (transparent || ignore_no_data)
5127 {
5128 /* already transparent or missing NO-DATA value */
5129 if (transparent)
5130 {
5131 update_no_data_stats (st);
5132 p_in++;
5133 }
5134 else
5135 {
5136 /* opaque pixel */
5137 double value = *p_in++;
5138 update_count_stats (st);
5139 update_stats (st, 0, value);
5140 }
5141 }
5142 else
5143 {
5144 /* testing for NO-DATA values */
5145 int match = 0;
5146 const char *p_save = p_in;
5147 char sample = 0;
5148 rl2_get_pixel_sample_int8 (no_data, &sample);
5149 if (sample == *p_in++)
5150 match++;
5151 if (match != 1)
5152 {
5153 /* opaque pixel */
5154 double value;
5155 p_in = p_save;
5156 value = *p_in++;
5157 update_count_stats (st);
5158 update_stats (st, 0, value);
5159 }
5160 else
5161 {
5162 /* NO-DATA pixel */
5163 update_no_data_stats (st);
5164 }
5165 }
5166 }
5167 }
5168 }
5169
5170 static void
update_uint8_stats(unsigned short width,unsigned short height,unsigned char num_bands,const unsigned char * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5171 update_uint8_stats (unsigned short width, unsigned short height,
5172 unsigned char num_bands,
5173 const unsigned char *pixels, const unsigned char *mask,
5174 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5175 {
5176 /* computing UINT8 tile statistics */
5177 int x;
5178 int y;
5179 int ib;
5180 const unsigned char *p_in = pixels;
5181 const unsigned char *p_msk = mask;
5182 int transparent;
5183 unsigned char sample_type;
5184 unsigned char pixel_type;
5185 unsigned char nbands;
5186 int ignore_no_data = 1;
5187
5188 if (no_data != NULL)
5189 {
5190 ignore_no_data = 0;
5191 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5192 != RL2_OK)
5193 ignore_no_data = 1;
5194 if (nbands != num_bands)
5195 ignore_no_data = 1;
5196 if (sample_type == RL2_SAMPLE_1_BIT || sample_type == RL2_SAMPLE_2_BIT
5197 || sample_type == RL2_SAMPLE_4_BIT
5198 || sample_type == RL2_SAMPLE_UINT8)
5199 ;
5200 else
5201 ignore_no_data = 1;
5202 }
5203
5204 for (y = 0; y < height; y++)
5205 {
5206 for (x = 0; x < width; x++)
5207 {
5208 transparent = 0;
5209 if (p_msk != NULL)
5210 {
5211 if (*p_msk++ == 0)
5212 transparent = 1;
5213 }
5214 if (transparent || ignore_no_data)
5215 {
5216 /* already transparent or missing NO-DATA value */
5217 if (transparent)
5218 {
5219 update_no_data_stats (st);
5220 for (ib = 0; ib < num_bands; ib++)
5221 p_in++;
5222 }
5223 else
5224 {
5225 /* opaque pixel */
5226 update_count_stats (st);
5227 for (ib = 0; ib < num_bands; ib++)
5228 {
5229 double value = *p_in++;
5230 update_stats (st, ib, value);
5231 }
5232 }
5233 }
5234 else
5235 {
5236 /* testing for NO-DATA values */
5237 int match = 0;
5238 const unsigned char *p_save = p_in;
5239 for (ib = 0; ib < num_bands; ib++)
5240 {
5241 unsigned char sample = 0;
5242 switch (sample_type)
5243 {
5244 case RL2_SAMPLE_1_BIT:
5245 rl2_get_pixel_sample_1bit (no_data, &sample);
5246 break;
5247 case RL2_SAMPLE_2_BIT:
5248 rl2_get_pixel_sample_2bit (no_data, &sample);
5249 break;
5250 case RL2_SAMPLE_4_BIT:
5251 rl2_get_pixel_sample_4bit (no_data, &sample);
5252 break;
5253 case RL2_SAMPLE_UINT8:
5254 rl2_get_pixel_sample_uint8 (no_data, ib,
5255 &sample);
5256 break;
5257 };
5258 if (sample == *p_in++)
5259 match++;
5260 }
5261 if (match != num_bands)
5262 {
5263 /* opaque pixel */
5264 update_count_stats (st);
5265 p_in = p_save;
5266 for (ib = 0; ib < num_bands; ib++)
5267 {
5268 double value = *p_in++;
5269 update_stats (st, ib, value);
5270 }
5271 }
5272 else
5273 {
5274 /* NO-DATA pixel */
5275 update_no_data_stats (st);
5276 }
5277 }
5278 }
5279 }
5280 }
5281
5282 static void
update_histogram(rl2PrivRasterStatisticsPtr st,int band,double value)5283 update_histogram (rl2PrivRasterStatisticsPtr st, int band, double value)
5284 {
5285 /* updating the Histogram */
5286 double interval;
5287 double step;
5288 double index;
5289 rl2PrivBandStatisticsPtr band_st = st->band_stats + band;
5290
5291 interval = band_st->max - band_st->min;
5292 step = interval / ((double) (band_st->nHistogram) - 1.0);
5293 index = floor ((value - band_st->min) / step);
5294 if (index < 0.0)
5295 index = 0.0;
5296 if (index > 255.0)
5297 index = 255.0;
5298 *(band_st->histogram + (unsigned int) index) += 1.0;
5299 }
5300
5301 static void
compute_int16_histogram(unsigned short width,unsigned short height,const short * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5302 compute_int16_histogram (unsigned short width, unsigned short height,
5303 const short *pixels, const unsigned char *mask,
5304 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5305 {
5306 /* computing INT16 tile histogram */
5307 int x;
5308 int y;
5309 const short *p_in = pixels;
5310 const unsigned char *p_msk = mask;
5311 int transparent;
5312 unsigned char sample_type;
5313 unsigned char pixel_type;
5314 unsigned char nbands;
5315 int ignore_no_data = 1;
5316
5317 if (no_data != NULL)
5318 {
5319 ignore_no_data = 0;
5320 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5321 != RL2_OK)
5322 ignore_no_data = 1;
5323 if (nbands != 1)
5324 ignore_no_data = 1;
5325 if (sample_type == RL2_SAMPLE_INT16)
5326 ;
5327 else
5328 ignore_no_data = 1;
5329 }
5330
5331 for (y = 0; y < height; y++)
5332 {
5333 for (x = 0; x < width; x++)
5334 {
5335 transparent = 0;
5336 if (p_msk != NULL)
5337 {
5338 if (*p_msk++ == 0)
5339 transparent = 1;
5340 }
5341 if (transparent || ignore_no_data)
5342 {
5343 /* already transparent or missing NO-DATA value */
5344 if (transparent)
5345 p_in++;
5346 else
5347 {
5348 /* opaque pixel */
5349 double value = *p_in++;
5350 update_histogram (st, 0, value);
5351 }
5352 }
5353 else
5354 {
5355 /* testing for NO-DATA values */
5356 int match = 0;
5357 const short *p_save = p_in;
5358 short sample = 0;
5359 rl2_get_pixel_sample_int16 (no_data, &sample);
5360 if (sample == *p_in++)
5361 match++;
5362 if (match != 1)
5363 {
5364 /* opaque pixel */
5365 double value;
5366 p_in = p_save;
5367 value = *p_in++;
5368 update_histogram (st, 0, value);
5369 }
5370 }
5371 }
5372 }
5373 }
5374
5375 static void
update_int16_stats(unsigned short width,unsigned short height,const short * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5376 update_int16_stats (unsigned short width, unsigned short height,
5377 const short *pixels, const unsigned char *mask,
5378 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5379 {
5380 /* computing INT16 tile statistics */
5381 int x;
5382 int y;
5383 const short *p_in = pixels;
5384 const unsigned char *p_msk = mask;
5385 int transparent;
5386 unsigned char sample_type;
5387 unsigned char pixel_type;
5388 unsigned char nbands;
5389 int ignore_no_data = 1;
5390
5391 if (no_data != NULL)
5392 {
5393 ignore_no_data = 0;
5394 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5395 != RL2_OK)
5396 ignore_no_data = 1;
5397 if (nbands != 1)
5398 ignore_no_data = 1;
5399 if (sample_type == RL2_SAMPLE_INT16)
5400 ;
5401 else
5402 ignore_no_data = 1;
5403 }
5404
5405 for (y = 0; y < height; y++)
5406 {
5407 for (x = 0; x < width; x++)
5408 {
5409 transparent = 0;
5410 if (p_msk != NULL)
5411 {
5412 if (*p_msk++ == 0)
5413 transparent = 1;
5414 }
5415 if (transparent || ignore_no_data)
5416 {
5417 /* already transparent or missing NO-DATA value */
5418 if (transparent)
5419 {
5420 update_no_data_stats (st);
5421 p_in++;
5422 }
5423 else
5424 {
5425 /* opaque pixel */
5426 double value = *p_in++;
5427 update_count_stats (st);
5428 update_stats (st, 0, value);
5429 }
5430 }
5431 else
5432 {
5433 /* testing for NO-DATA values */
5434 int match = 0;
5435 const short *p_save = p_in;
5436 short sample = 0;
5437 rl2_get_pixel_sample_int16 (no_data, &sample);
5438 if (sample == *p_in++)
5439 match++;
5440 if (match != 1)
5441 {
5442 /* opaque pixel */
5443 double value;
5444 p_in = p_save;
5445 value = *p_in++;
5446 update_count_stats (st);
5447 update_stats (st, 0, value);
5448 }
5449 else
5450 {
5451 /* NO-DATA pixel */
5452 update_no_data_stats (st);
5453 }
5454 }
5455 }
5456 }
5457 compute_int16_histogram (width, height, pixels, mask, st, no_data);
5458 }
5459
5460 static void
compute_uint16_histogram(unsigned short width,unsigned short height,unsigned char num_bands,const unsigned short * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5461 compute_uint16_histogram (unsigned short width, unsigned short height,
5462 unsigned char num_bands,
5463 const unsigned short *pixels,
5464 const unsigned char *mask,
5465 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5466 {
5467 /* computing INT16 tile histogram */
5468 int x;
5469 int y;
5470 int ib;
5471 const unsigned short *p_in = pixels;
5472 const unsigned char *p_msk = mask;
5473 int transparent;
5474 unsigned char sample_type;
5475 unsigned char pixel_type;
5476 unsigned char nbands;
5477 int ignore_no_data = 1;
5478
5479 if (no_data != NULL)
5480 {
5481 ignore_no_data = 0;
5482 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5483 != RL2_OK)
5484 ignore_no_data = 1;
5485 if (nbands != num_bands)
5486 ignore_no_data = 1;
5487 if (sample_type == RL2_SAMPLE_UINT16)
5488 ;
5489 else
5490 ignore_no_data = 1;
5491 }
5492
5493 for (y = 0; y < height; y++)
5494 {
5495 for (x = 0; x < width; x++)
5496 {
5497 transparent = 0;
5498 if (p_msk != NULL)
5499 {
5500 if (*p_msk++ == 0)
5501 transparent = 1;
5502 }
5503 if (transparent || ignore_no_data)
5504 {
5505 /* already transparent or missing NO-DATA value */
5506 if (transparent)
5507 {
5508 for (ib = 0; ib < num_bands; ib++)
5509 p_in++;
5510 }
5511 else
5512 {
5513 /* opaque pixel */
5514 for (ib = 0; ib < num_bands; ib++)
5515 {
5516 double value = *p_in++;
5517 update_histogram (st, ib, value);
5518 }
5519 }
5520 }
5521 else
5522 {
5523 /* testing for NO-DATA values */
5524 int match = 0;
5525 const unsigned short *p_save = p_in;
5526 for (ib = 0; ib < num_bands; ib++)
5527 {
5528 unsigned short sample = 0;
5529 rl2_get_pixel_sample_uint16 (no_data, ib, &sample);
5530 if (sample == *p_in++)
5531 match++;
5532 }
5533 if (match != num_bands)
5534 {
5535 /* opaque pixel */
5536 p_in = p_save;
5537 for (ib = 0; ib < num_bands; ib++)
5538 {
5539 double value = *p_in++;
5540 update_histogram (st, ib, value);
5541 }
5542 }
5543 }
5544 }
5545 }
5546 }
5547
5548 static void
update_uint16_stats(unsigned short width,unsigned short height,unsigned char num_bands,const unsigned short * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5549 update_uint16_stats (unsigned short width, unsigned short height,
5550 unsigned char num_bands,
5551 const unsigned short *pixels, const unsigned char *mask,
5552 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5553 {
5554 /* computing UINT16 tile statistics */
5555 int x;
5556 int y;
5557 int ib;
5558 const unsigned short *p_in = pixels;
5559 const unsigned char *p_msk = mask;
5560 int transparent;
5561 unsigned char sample_type;
5562 unsigned char pixel_type;
5563 unsigned char nbands;
5564 int ignore_no_data = 1;
5565
5566 if (no_data != NULL)
5567 {
5568 ignore_no_data = 0;
5569 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5570 != RL2_OK)
5571 ignore_no_data = 1;
5572 if (nbands != num_bands)
5573 ignore_no_data = 1;
5574 if (sample_type == RL2_SAMPLE_UINT16)
5575 ;
5576 else
5577 ignore_no_data = 1;
5578 }
5579
5580 for (y = 0; y < height; y++)
5581 {
5582 for (x = 0; x < width; x++)
5583 {
5584 transparent = 0;
5585 if (p_msk != NULL)
5586 {
5587 if (*p_msk++ == 0)
5588 transparent = 1;
5589 }
5590 if (transparent || ignore_no_data)
5591 {
5592 /* already transparent or missing NO-DATA value */
5593 if (transparent)
5594 {
5595 update_no_data_stats (st);
5596 for (ib = 0; ib < num_bands; ib++)
5597 p_in++;
5598 }
5599 else
5600 {
5601 /* opaque pixel */
5602 update_count_stats (st);
5603 for (ib = 0; ib < num_bands; ib++)
5604 {
5605 double value = *p_in++;
5606 update_stats (st, ib, value);
5607 }
5608 }
5609 }
5610 else
5611 {
5612 /* testing for NO-DATA values */
5613 int match = 0;
5614 const unsigned short *p_save = p_in;
5615 for (ib = 0; ib < num_bands; ib++)
5616 {
5617 unsigned short sample = 0;
5618 rl2_get_pixel_sample_uint16 (no_data, ib, &sample);
5619 if (sample == *p_in++)
5620 match++;
5621 }
5622 if (match != num_bands)
5623 {
5624 /* opaque pixel */
5625 update_count_stats (st);
5626 p_in = p_save;
5627 for (ib = 0; ib < num_bands; ib++)
5628 {
5629 double value = *p_in++;
5630 update_stats (st, ib, value);
5631 }
5632 }
5633 else
5634 {
5635 /* NO-DATA pixel */
5636 update_no_data_stats (st);
5637 }
5638 }
5639 }
5640 }
5641 compute_uint16_histogram (width, height, num_bands, pixels, mask, st,
5642 no_data);
5643 }
5644
5645 static void
compute_int32_histogram(unsigned short width,unsigned short height,const int * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5646 compute_int32_histogram (unsigned short width, unsigned short height,
5647 const int *pixels, const unsigned char *mask,
5648 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5649 {
5650 /* computing INT16 tile histogram */
5651 int x;
5652 int y;
5653 const int *p_in = pixels;
5654 const unsigned char *p_msk = mask;
5655 int transparent;
5656 unsigned char sample_type;
5657 unsigned char pixel_type;
5658 unsigned char nbands;
5659 int ignore_no_data = 1;
5660
5661 if (no_data != NULL)
5662 {
5663 ignore_no_data = 0;
5664 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5665 != RL2_OK)
5666 ignore_no_data = 1;
5667 if (nbands != 1)
5668 ignore_no_data = 1;
5669 if (sample_type == RL2_SAMPLE_INT32)
5670 ;
5671 else
5672 ignore_no_data = 1;
5673 }
5674
5675 for (y = 0; y < height; y++)
5676 {
5677 for (x = 0; x < width; x++)
5678 {
5679 transparent = 0;
5680 if (p_msk != NULL)
5681 {
5682 if (*p_msk++ == 0)
5683 transparent = 1;
5684 }
5685 if (transparent || ignore_no_data)
5686 {
5687 /* already transparent or missing NO-DATA value */
5688 if (transparent)
5689 p_in++;
5690 else
5691 {
5692 /* opaque pixel */
5693 double value = *p_in++;
5694 update_histogram (st, 0, value);
5695 }
5696 }
5697 else
5698 {
5699 /* testing for NO-DATA values */
5700 int match = 0;
5701 const int *p_save = p_in;
5702 int sample = 0;
5703 rl2_get_pixel_sample_int32 (no_data, &sample);
5704 if (sample == *p_in++)
5705 match++;
5706 if (match != 1)
5707 {
5708 /* opaque pixel */
5709 double value;
5710 p_in = p_save;
5711 value = *p_in++;
5712 update_histogram (st, 0, value);
5713 }
5714 }
5715 }
5716 }
5717 }
5718
5719 static void
update_int32_stats(unsigned short width,unsigned short height,const int * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5720 update_int32_stats (unsigned short width, unsigned short height,
5721 const int *pixels, const unsigned char *mask,
5722 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5723 {
5724 /* computing INT32 tile statistics */
5725 int x;
5726 int y;
5727 const int *p_in = pixels;
5728 const unsigned char *p_msk = mask;
5729 int transparent;
5730 unsigned char sample_type;
5731 unsigned char pixel_type;
5732 unsigned char nbands;
5733 int ignore_no_data = 1;
5734
5735 if (no_data != NULL)
5736 {
5737 ignore_no_data = 0;
5738 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5739 != RL2_OK)
5740 ignore_no_data = 1;
5741 if (nbands != 1)
5742 ignore_no_data = 1;
5743 if (sample_type == RL2_SAMPLE_INT32)
5744 ;
5745 else
5746 ignore_no_data = 1;
5747 }
5748
5749 for (y = 0; y < height; y++)
5750 {
5751 for (x = 0; x < width; x++)
5752 {
5753 transparent = 0;
5754 if (p_msk != NULL)
5755 {
5756 if (*p_msk++ == 0)
5757 transparent = 1;
5758 }
5759 if (transparent || ignore_no_data)
5760 {
5761 /* already transparent or missing NO-DATA value */
5762 if (transparent)
5763 {
5764 update_no_data_stats (st);
5765 p_in++;
5766 }
5767 else
5768 {
5769 /* opaque pixel */
5770 double value = *p_in++;
5771 update_count_stats (st);
5772 update_stats (st, 0, value);
5773 }
5774 }
5775 else
5776 {
5777 /* testing for NO-DATA values */
5778 int match = 0;
5779 const int *p_save = p_in;
5780 int sample = 0;
5781 rl2_get_pixel_sample_int32 (no_data, &sample);
5782 if (sample == *p_in++)
5783 match++;
5784 if (match != 1)
5785 {
5786 /* opaque pixel */
5787 double value;
5788 p_in = p_save;
5789 value = *p_in++;
5790 update_count_stats (st);
5791 update_stats (st, 0, value);
5792 }
5793 else
5794 {
5795 /* NO-DATA pixel */
5796 update_no_data_stats (st);
5797 }
5798 }
5799 }
5800 }
5801 compute_int32_histogram (width, height, pixels, mask, st, no_data);
5802 }
5803
5804 static void
compute_uint32_histogram(unsigned short width,unsigned short height,const unsigned int * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5805 compute_uint32_histogram (unsigned short width, unsigned short height,
5806 const unsigned int *pixels, const unsigned char *mask,
5807 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5808 {
5809 /* computing INT16 tile histogram */
5810 int x;
5811 int y;
5812 const unsigned int *p_in = pixels;
5813 const unsigned char *p_msk = mask;
5814 int transparent;
5815 unsigned char sample_type;
5816 unsigned char pixel_type;
5817 unsigned char nbands;
5818 int ignore_no_data = 1;
5819
5820 if (no_data != NULL)
5821 {
5822 ignore_no_data = 0;
5823 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5824 != RL2_OK)
5825 ignore_no_data = 1;
5826 if (nbands != 1)
5827 ignore_no_data = 1;
5828 if (sample_type == RL2_SAMPLE_UINT32)
5829 ;
5830 else
5831 ignore_no_data = 1;
5832 }
5833
5834 for (y = 0; y < height; y++)
5835 {
5836 for (x = 0; x < width; x++)
5837 {
5838 transparent = 0;
5839 if (p_msk != NULL)
5840 {
5841 if (*p_msk++ == 0)
5842 transparent = 1;
5843 }
5844 if (transparent || ignore_no_data)
5845 {
5846 /* already transparent or missing NO-DATA value */
5847 if (transparent)
5848 p_in++;
5849 else
5850 {
5851 /* opaque pixel */
5852 double value = *p_in++;
5853 update_histogram (st, 0, value);
5854 }
5855 }
5856 else
5857 {
5858 /* testing for NO-DATA values */
5859 int match = 0;
5860 const unsigned int *p_save = p_in;
5861 unsigned int sample = 0;
5862 rl2_get_pixel_sample_uint32 (no_data, &sample);
5863 if (sample == *p_in++)
5864 match++;
5865 if (match != 1)
5866 {
5867 /* opaque pixel */
5868 double value;
5869 p_in = p_save;
5870 value = *p_in++;
5871 update_histogram (st, 0, value);
5872 }
5873 }
5874 }
5875 }
5876 }
5877
5878 static void
update_uint32_stats(unsigned short width,unsigned short height,const unsigned int * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5879 update_uint32_stats (unsigned short width, unsigned short height,
5880 const unsigned int *pixels, const unsigned char *mask,
5881 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5882 {
5883 /* computing UINT32 tile statistics */
5884 int x;
5885 int y;
5886 const unsigned int *p_in = pixels;
5887 const unsigned char *p_msk = mask;
5888 int transparent;
5889 unsigned char sample_type;
5890 unsigned char pixel_type;
5891 unsigned char nbands;
5892 int ignore_no_data = 1;
5893
5894 if (no_data != NULL)
5895 {
5896 ignore_no_data = 0;
5897 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5898 != RL2_OK)
5899 ignore_no_data = 1;
5900 if (nbands != 1)
5901 ignore_no_data = 1;
5902 if (sample_type == RL2_SAMPLE_UINT32)
5903 ;
5904 else
5905 ignore_no_data = 1;
5906 }
5907
5908 for (y = 0; y < height; y++)
5909 {
5910 for (x = 0; x < width; x++)
5911 {
5912 transparent = 0;
5913 if (p_msk != NULL)
5914 {
5915 if (*p_msk++ == 0)
5916 transparent = 1;
5917 }
5918 if (transparent || ignore_no_data)
5919 {
5920 /* already transparent or missing NO-DATA value */
5921 if (transparent)
5922 {
5923 update_no_data_stats (st);
5924 p_in++;
5925 }
5926 else
5927 {
5928 /* opaque pixel */
5929 double value = *p_in++;
5930 update_count_stats (st);
5931 update_stats (st, 0, value);
5932 }
5933 }
5934 else
5935 {
5936 /* testing for NO-DATA values */
5937 int match = 0;
5938 const unsigned int *p_save = p_in;
5939 unsigned int sample = 0;
5940 rl2_get_pixel_sample_uint32 (no_data, &sample);
5941 if (sample == *p_in++)
5942 match++;
5943 if (match != 1)
5944 {
5945 /* opaque pixel */
5946 double value;
5947 p_in = p_save;
5948 value = *p_in++;
5949 update_count_stats (st);
5950 update_stats (st, 0, value);
5951 }
5952 else
5953 {
5954 /* NO-DATA pixel */
5955 update_no_data_stats (st);
5956 }
5957 }
5958 }
5959 }
5960 compute_uint32_histogram (width, height, pixels, mask, st, no_data);
5961 }
5962
5963 static void
compute_float_histogram(unsigned short width,unsigned short height,const float * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)5964 compute_float_histogram (unsigned short width, unsigned short height,
5965 const float *pixels, const unsigned char *mask,
5966 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
5967 {
5968 /* computing FLOAT tile histogram */
5969 int x;
5970 int y;
5971 const float *p_in = pixels;
5972 const unsigned char *p_msk = mask;
5973 int transparent;
5974 unsigned char sample_type;
5975 unsigned char pixel_type;
5976 unsigned char nbands;
5977 int ignore_no_data = 1;
5978
5979 if (no_data != NULL)
5980 {
5981 ignore_no_data = 0;
5982 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
5983 != RL2_OK)
5984 ignore_no_data = 1;
5985 if (nbands != 1)
5986 ignore_no_data = 1;
5987 if (sample_type == RL2_SAMPLE_FLOAT)
5988 ;
5989 else
5990 ignore_no_data = 1;
5991 }
5992
5993 for (y = 0; y < height; y++)
5994 {
5995 for (x = 0; x < width; x++)
5996 {
5997 transparent = 0;
5998 if (p_msk != NULL)
5999 {
6000 if (*p_msk++ == 0)
6001 transparent = 1;
6002 }
6003 if (transparent || ignore_no_data)
6004 {
6005 /* already transparent or missing NO-DATA value */
6006 if (transparent)
6007 p_in++;
6008 else
6009 {
6010 /* opaque pixel */
6011 double value = *p_in++;
6012 update_histogram (st, 0, value);
6013 }
6014 }
6015 else
6016 {
6017 /* testing for NO-DATA values */
6018 int match = 0;
6019 const float *p_save = p_in;
6020 float sample = 0;
6021 rl2_get_pixel_sample_float (no_data, &sample);
6022 if (sample == *p_in++)
6023 match++;
6024 if (match != 1)
6025 {
6026 /* opaque pixel */
6027 double value;
6028 p_in = p_save;
6029 value = *p_in++;
6030 update_histogram (st, 0, value);
6031 }
6032 }
6033 }
6034 }
6035 }
6036
6037 static void
update_float_stats(unsigned short width,unsigned short height,const float * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)6038 update_float_stats (unsigned short width, unsigned short height,
6039 const float *pixels, const unsigned char *mask,
6040 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
6041 {
6042 /* computing FLOAT tile statistics */
6043 int x;
6044 int y;
6045 const float *p_in = pixels;
6046 const unsigned char *p_msk = mask;
6047 int transparent;
6048 unsigned char sample_type;
6049 unsigned char pixel_type;
6050 unsigned char nbands;
6051 int ignore_no_data = 1;
6052
6053 if (no_data != NULL)
6054 {
6055 ignore_no_data = 0;
6056 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
6057 != RL2_OK)
6058 ignore_no_data = 1;
6059 if (nbands != 1)
6060 ignore_no_data = 1;
6061 if (sample_type == RL2_SAMPLE_FLOAT)
6062 ;
6063 else
6064 ignore_no_data = 1;
6065 }
6066
6067 for (y = 0; y < height; y++)
6068 {
6069 for (x = 0; x < width; x++)
6070 {
6071 transparent = 0;
6072 if (p_msk != NULL)
6073 {
6074 if (*p_msk++ == 0)
6075 transparent = 1;
6076 }
6077 if (transparent || ignore_no_data)
6078 {
6079 /* already transparent or missing NO-DATA value */
6080 if (transparent)
6081 {
6082 update_no_data_stats (st);
6083 p_in++;
6084 }
6085 else
6086 {
6087 /* opaque pixel */
6088 double value = *p_in++;
6089 update_count_stats (st);
6090 update_stats (st, 0, value);
6091 }
6092 }
6093 else
6094 {
6095 /* testing for NO-DATA values */
6096 int match = 0;
6097 const float *p_save = p_in;
6098 float sample = 0.0;
6099 rl2_get_pixel_sample_float (no_data, &sample);
6100 if (sample == *p_in++)
6101 match++;
6102 if (match != 1)
6103 {
6104 /* opaque pixel */
6105 double value;
6106 p_in = p_save;
6107 value = *p_in++;
6108 update_count_stats (st);
6109 update_stats (st, 0, value);
6110 }
6111 else
6112 {
6113 /* NO-DATA pixel */
6114 update_no_data_stats (st);
6115 }
6116 }
6117 }
6118 }
6119 compute_float_histogram (width, height, pixels, mask, st, no_data);
6120 }
6121
6122 static void
compute_double_histogram(unsigned short width,unsigned short height,const double * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)6123 compute_double_histogram (unsigned short width, unsigned short height,
6124 const double *pixels, const unsigned char *mask,
6125 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
6126 {
6127 /* computing INT16 tile histogram */
6128 int x;
6129 int y;
6130 const double *p_in = pixels;
6131 const unsigned char *p_msk = mask;
6132 int transparent;
6133 unsigned char sample_type;
6134 unsigned char pixel_type;
6135 unsigned char nbands;
6136 int ignore_no_data = 1;
6137
6138 if (no_data != NULL)
6139 {
6140 ignore_no_data = 0;
6141 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
6142 != RL2_OK)
6143 ignore_no_data = 1;
6144 if (nbands != 1)
6145 ignore_no_data = 1;
6146 if (sample_type == RL2_SAMPLE_DOUBLE)
6147 ;
6148 else
6149 ignore_no_data = 1;
6150 }
6151
6152 for (y = 0; y < height; y++)
6153 {
6154 for (x = 0; x < width; x++)
6155 {
6156 transparent = 0;
6157 if (p_msk != NULL)
6158 {
6159 if (*p_msk++ == 0)
6160 transparent = 1;
6161 }
6162 if (transparent || ignore_no_data)
6163 {
6164 /* already transparent or missing NO-DATA value */
6165 if (transparent)
6166 p_in++;
6167 else
6168 {
6169 /* opaque pixel */
6170 double value = *p_in++;
6171 update_histogram (st, 0, value);
6172 }
6173 }
6174 else
6175 {
6176 /* testing for NO-DATA values */
6177 int match = 0;
6178 const double *p_save = p_in;
6179 double sample = 0;
6180 rl2_get_pixel_sample_double (no_data, &sample);
6181 if (sample == *p_in++)
6182 match++;
6183 if (match != 1)
6184 {
6185 /* opaque pixel */
6186 double value;
6187 p_in = p_save;
6188 value = *p_in++;
6189 update_histogram (st, 0, value);
6190 }
6191 }
6192 }
6193 }
6194 }
6195
6196 static void
update_double_stats(unsigned short width,unsigned short height,const double * pixels,const unsigned char * mask,rl2PrivRasterStatisticsPtr st,rl2PixelPtr no_data)6197 update_double_stats (unsigned short width, unsigned short height,
6198 const double *pixels, const unsigned char *mask,
6199 rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
6200 {
6201 /* computing DOUBLE tile statistics */
6202 int x;
6203 int y;
6204 const double *p_in = pixels;
6205 const unsigned char *p_msk = mask;
6206 int transparent;
6207 unsigned char sample_type;
6208 unsigned char pixel_type;
6209 unsigned char nbands;
6210 int ignore_no_data = 1;
6211
6212 if (no_data != NULL)
6213 {
6214 ignore_no_data = 0;
6215 if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
6216 != RL2_OK)
6217 ignore_no_data = 1;
6218 if (nbands != 1)
6219 ignore_no_data = 1;
6220 if (sample_type == RL2_SAMPLE_DOUBLE)
6221 ;
6222 else
6223 ignore_no_data = 1;
6224 }
6225
6226 for (y = 0; y < height; y++)
6227 {
6228 for (x = 0; x < width; x++)
6229 {
6230 transparent = 0;
6231 if (p_msk != NULL)
6232 {
6233 if (*p_msk++ == 0)
6234 transparent = 1;
6235 }
6236 if (transparent || ignore_no_data)
6237 {
6238 /* already transparent or missing NO-DATA value */
6239 if (transparent)
6240 {
6241 update_no_data_stats (st);
6242 p_in++;
6243 }
6244 else
6245 {
6246 /* opaque pixel */
6247 double value = *p_in++;
6248 update_count_stats (st);
6249 update_stats (st, 0, value);
6250 }
6251 }
6252 else
6253 {
6254 /* testing for NO-DATA values */
6255 int match = 0;
6256 const double *p_save = p_in;
6257 double sample = 0.0;
6258 rl2_get_pixel_sample_double (no_data, &sample);
6259 if (sample == *p_in++)
6260 match++;
6261 if (match != 1)
6262 {
6263 /* opaque pixel */
6264 double value;
6265 p_in = p_save;
6266 value = *p_in++;
6267 update_count_stats (st);
6268 update_stats (st, 0, value);
6269 }
6270 else
6271 {
6272 /* NO-DATA pixel */
6273 update_no_data_stats (st);
6274 }
6275 }
6276 }
6277 }
6278 compute_double_histogram (width, height, pixels, mask, st, no_data);
6279 }
6280
6281 RL2_DECLARE rl2RasterStatisticsPtr
rl2_build_raster_statistics(rl2RasterPtr raster,rl2PixelPtr noData)6282 rl2_build_raster_statistics (rl2RasterPtr raster, rl2PixelPtr noData)
6283 {
6284 /*
6285 / building a statistics object from a Raster object
6286 */
6287 rl2PrivRasterStatisticsPtr st;
6288 rl2RasterStatisticsPtr stats = NULL;
6289 rl2PrivRasterPtr rst;
6290 if (raster == NULL)
6291 goto error;
6292 rst = (rl2PrivRasterPtr) raster;
6293
6294 stats = rl2_create_raster_statistics (rst->sampleType, rst->nBands);
6295 if (stats == NULL)
6296 goto error;
6297 st = (rl2PrivRasterStatisticsPtr) stats;
6298
6299 switch (rst->sampleType)
6300 {
6301 case RL2_SAMPLE_1_BIT:
6302 case RL2_SAMPLE_2_BIT:
6303 case RL2_SAMPLE_4_BIT:
6304 case RL2_SAMPLE_UINT8:
6305 update_uint8_stats (rst->width, rst->height, rst->nBands,
6306 (const unsigned char *) (rst->rasterBuffer),
6307 rst->maskBuffer, st, noData);
6308 break;
6309 case RL2_SAMPLE_INT8:
6310 update_int8_stats (rst->width, rst->height,
6311 (const char *) (rst->rasterBuffer),
6312 rst->maskBuffer, st, noData);
6313 break;
6314 case RL2_SAMPLE_UINT16:
6315 update_uint16_stats (rst->width, rst->height, rst->nBands,
6316 (const unsigned short *) (rst->rasterBuffer),
6317 rst->maskBuffer, st, noData);
6318 break;
6319 case RL2_SAMPLE_INT16:
6320 update_int16_stats (rst->width, rst->height,
6321 (const short *) (rst->rasterBuffer),
6322 rst->maskBuffer, st, noData);
6323 break;
6324 case RL2_SAMPLE_UINT32:
6325 update_uint32_stats (rst->width, rst->height,
6326 (const unsigned int *) (rst->rasterBuffer),
6327 rst->maskBuffer, st, noData);
6328 break;
6329 case RL2_SAMPLE_INT32:
6330 update_int32_stats (rst->width, rst->height,
6331 (const int *) (rst->rasterBuffer),
6332 rst->maskBuffer, st, noData);
6333 break;
6334 case RL2_SAMPLE_FLOAT:
6335 update_float_stats (rst->width, rst->height,
6336 (const float *) (rst->rasterBuffer),
6337 rst->maskBuffer, st, noData);
6338 break;
6339 case RL2_SAMPLE_DOUBLE:
6340 update_double_stats (rst->width, rst->height,
6341 (const double *) (rst->rasterBuffer),
6342 rst->maskBuffer, st, noData);
6343 break;
6344 };
6345 return stats;
6346
6347 error:
6348 if (stats != NULL)
6349 rl2_destroy_raster_statistics (stats);
6350 return NULL;
6351 }
6352
6353 RL2_DECLARE rl2RasterStatisticsPtr
rl2_get_raster_statistics(const unsigned char * blob_odd,int blob_odd_sz,const unsigned char * blob_even,int blob_even_sz,rl2PalettePtr palette,rl2PixelPtr noData)6354 rl2_get_raster_statistics (const unsigned char *blob_odd,
6355 int blob_odd_sz, const unsigned char *blob_even,
6356 int blob_even_sz, rl2PalettePtr palette,
6357 rl2PixelPtr noData)
6358 {
6359 /*
6360 / decoding from internal RL2 binary format to Raster and
6361 / building the corresponding statistics object
6362 */
6363 rl2RasterStatisticsPtr stats = NULL;
6364 rl2RasterPtr raster =
6365 rl2_raster_decode (RL2_SCALE_1, blob_odd, blob_odd_sz, blob_even,
6366 blob_even_sz, palette);
6367 if (raster == NULL)
6368 goto error;
6369 palette = NULL;
6370
6371 stats = rl2_build_raster_statistics (raster, noData);
6372 if (stats == NULL)
6373 goto error;
6374 rl2_destroy_raster (raster);
6375 return stats;
6376
6377 error:
6378 if (raster != NULL)
6379 rl2_destroy_raster (raster);
6380 if (palette != NULL)
6381 rl2_destroy_palette (palette);
6382 if (stats != NULL)
6383 rl2_destroy_raster_statistics (stats);
6384 return NULL;
6385 }
6386
6387 RL2_DECLARE int
rl2_serialize_dbms_palette(rl2PalettePtr palette,unsigned char ** blob,int * blob_size)6388 rl2_serialize_dbms_palette (rl2PalettePtr palette, unsigned char **blob,
6389 int *blob_size)
6390 {
6391 /* creating a Palette (DBMS serialized format) */
6392 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) palette;
6393 rl2PrivPaletteEntryPtr entry;
6394 int sz = 12;
6395 uLong crc;
6396 int i;
6397 int endian_arch = endianArch ();
6398 unsigned char *p;
6399 unsigned char *ptr;
6400
6401 if (plt == NULL)
6402 return RL2_ERROR;
6403
6404 sz += plt->nEntries * 3;
6405 p = malloc (sz);
6406 if (p == NULL)
6407 return RL2_ERROR;
6408 ptr = p;
6409
6410 *ptr++ = 0x00; /* start marker */
6411 *ptr++ = RL2_DATA_START;
6412 *ptr++ = RL2_LITTLE_ENDIAN;
6413 exportU16 (ptr, plt->nEntries, 1, endian_arch); /* # Palette entries */
6414 ptr += 2;
6415 *ptr++ = RL2_PALETTE_START;
6416 for (i = 0; i < plt->nEntries; i++)
6417 {
6418 entry = plt->entries + i;
6419 *ptr++ = entry->red;
6420 *ptr++ = entry->green;
6421 *ptr++ = entry->blue;
6422 }
6423 *ptr++ = RL2_PALETTE_END;
6424 /* computing the CRC32 */
6425 crc = crc32 (0L, p, ptr - p);
6426 exportU32 (ptr, crc, 1, endian_arch); /* the Palette own CRC */
6427 ptr += 4;
6428 *ptr++ = RL2_DATA_END;
6429 *blob = p;
6430 *blob_size = sz;
6431 return RL2_OK;
6432 }
6433
6434 static int
check_serialized_palette(const unsigned char * blob,int blob_size)6435 check_serialized_palette (const unsigned char *blob, int blob_size)
6436 {
6437 /* checking a Raster Statistics serialized object from validity */
6438 uLong crc;
6439 uLong oldCrc;
6440 const unsigned char *ptr = blob;
6441 int endian;
6442 unsigned short nEntries;
6443 int endian_arch = endianArch ();
6444 if (blob == NULL)
6445 return 0;
6446 if (blob_size < 12)
6447 return 0;
6448
6449 if (*ptr++ != 0x00)
6450 return 0; /* invalid start signature */
6451 if (*ptr++ != RL2_DATA_START)
6452 return 0; /* invalid start signature */
6453 endian = *ptr++;
6454 if (endian == RL2_LITTLE_ENDIAN || endian == RL2_BIG_ENDIAN)
6455 ;
6456 else
6457 return 0; /* invalid endiannes */
6458 nEntries = importU16 (ptr, endian, endian_arch);
6459 ptr += 2;
6460 if (blob_size != 12 + (nEntries * 3))
6461 return 0; /* invalid size */
6462 if (*ptr++ != RL2_PALETTE_START)
6463 return 0; /* invalid start marker */
6464 ptr += nEntries * 3;
6465 if (*ptr++ != RL2_PALETTE_END)
6466 return 0;
6467 /* computing the CRC32 */
6468 crc = crc32 (0L, blob, ptr - blob);
6469 oldCrc = importU32 (ptr, endian, endian_arch);
6470 ptr += 4;
6471 if (crc != oldCrc)
6472 return 0;
6473 if (*ptr != RL2_DATA_END)
6474 return 0; /* invalid end signature */
6475 return 1;
6476 }
6477
6478 RL2_DECLARE int
rl2_is_valid_dbms_palette(const unsigned char * blob,int blob_size,unsigned char sample_type)6479 rl2_is_valid_dbms_palette (const unsigned char *blob, int blob_size,
6480 unsigned char sample_type)
6481 {
6482 /* testing a serialized Palette object for validity */
6483 const unsigned char *ptr;
6484 int endian;
6485 unsigned short nEntries;
6486 int endian_arch = endianArch ();
6487 if (!check_serialized_palette (blob, blob_size))
6488 return RL2_ERROR;
6489 ptr = blob + 2;
6490 endian = *ptr++;
6491 nEntries = importU16 (ptr, endian, endian_arch);
6492 if (sample_type == RL2_SAMPLE_1_BIT || sample_type == RL2_SAMPLE_2_BIT
6493 || sample_type == RL2_SAMPLE_4_BIT || sample_type == RL2_SAMPLE_UINT8)
6494 ;
6495 else
6496 return RL2_ERROR;
6497 if (sample_type == RL2_SAMPLE_1_BIT && nEntries > 2)
6498 return RL2_ERROR;
6499 if (sample_type == RL2_SAMPLE_2_BIT && nEntries > 4)
6500 return RL2_ERROR;
6501 if (sample_type == RL2_SAMPLE_4_BIT && nEntries > 16)
6502 return RL2_ERROR;
6503 if (sample_type == RL2_SAMPLE_UINT8 && nEntries > 256)
6504 return RL2_ERROR;
6505 return RL2_OK;
6506 }
6507
6508 RL2_DECLARE rl2PalettePtr
rl2_deserialize_dbms_palette(const unsigned char * blob,int blob_size)6509 rl2_deserialize_dbms_palette (const unsigned char *blob, int blob_size)
6510 {
6511 /* attempting to deserialize a Palette from DBMS binary format */
6512 rl2PalettePtr palette = NULL;
6513 int ip;
6514 const unsigned char *ptr;
6515 int endian;
6516 unsigned short nEntries;
6517 int endian_arch = endianArch ();
6518 if (blob == NULL)
6519 return NULL;
6520 if (blob_size < 12)
6521 return NULL;
6522
6523 if (!check_serialized_palette (blob, blob_size))
6524 return NULL;
6525 ptr = blob + 2;
6526 endian = *ptr++;
6527 nEntries = importU16 (ptr, endian, endian_arch);
6528 ptr += 3;
6529 palette = rl2_create_palette (nEntries);
6530 if (palette == NULL)
6531 return NULL;
6532 for (ip = 0; ip < nEntries; ip++)
6533 {
6534 unsigned char r = *ptr++;
6535 unsigned char g = *ptr++;
6536 unsigned char b = *ptr++;
6537 rl2_set_palette_color (palette, ip, r, g, b);
6538 }
6539 return palette;
6540 }
6541
6542 RL2_DECLARE int
rl2_serialize_dbms_raster_statistics(rl2RasterStatisticsPtr stats,unsigned char ** blob,int * blob_size)6543 rl2_serialize_dbms_raster_statistics (rl2RasterStatisticsPtr stats,
6544 unsigned char **blob, int *blob_size)
6545 {
6546 /* creating a Raster Statistics (DBMS serialized format) */
6547 rl2PrivRasterStatisticsPtr st = (rl2PrivRasterStatisticsPtr) stats;
6548 rl2PrivBandStatisticsPtr band;
6549 int sz = 26;
6550 uLong crc;
6551 int ib;
6552 int ih;
6553 int endian_arch = endianArch ();
6554 unsigned char *p;
6555 unsigned char *ptr;
6556
6557 *blob = NULL;
6558 *blob_size = 0;
6559 if (st == NULL)
6560 return RL2_ERROR;
6561
6562 for (ib = 0; ib < st->nBands; ib++)
6563 {
6564 band = st->band_stats + ib;
6565 sz += 38;
6566 sz += band->nHistogram * sizeof (double);
6567 }
6568 p = malloc (sz);
6569 if (p == NULL)
6570 return RL2_ERROR;
6571 ptr = p;
6572
6573 *ptr++ = 0x00; /* start marker */
6574 *ptr++ = RL2_STATS_START;
6575 *ptr++ = RL2_LITTLE_ENDIAN;
6576 *ptr++ = st->sampleType;
6577 *ptr++ = st->nBands;
6578 exportDouble (ptr, st->no_data, 1, endian_arch); /* # no_data values */
6579 ptr += 8;
6580 exportDouble (ptr, st->count, 1, endian_arch); /* # count */
6581 ptr += 8;
6582 for (ib = 0; ib < st->nBands; ib++)
6583 {
6584 *ptr++ = RL2_BAND_STATS_START;
6585 band = st->band_stats + ib;
6586 exportDouble (ptr, band->min, 1, endian_arch); /* # Min values */
6587 ptr += 8;
6588 exportDouble (ptr, band->max, 1, endian_arch); /* # Max values */
6589 ptr += 8;
6590 exportDouble (ptr, band->mean, 1, endian_arch); /* # Mean */
6591 ptr += 8;
6592 exportDouble (ptr, band->sum_sq_diff, 1, endian_arch); /* # sum of square differences */
6593 ptr += 8;
6594 exportU16 (ptr, band->nHistogram, 1, endian_arch); /* # Histogram entries */
6595 ptr += 2;
6596 *ptr++ = RL2_HISTOGRAM_START;
6597 for (ih = 0; ih < band->nHistogram; ih++)
6598 {
6599 exportDouble (ptr, *(band->histogram + ih), 1, endian_arch); /* # Histogram value */
6600 ptr += 8;
6601 }
6602 *ptr++ = RL2_HISTOGRAM_END;
6603 *ptr++ = RL2_BAND_STATS_END;
6604 }
6605 /* computing the CRC32 */
6606 crc = crc32 (0L, p, ptr - p);
6607 exportU32 (ptr, crc, 1, endian_arch); /* the Raster Statistics own CRC */
6608 ptr += 4;
6609 *ptr++ = RL2_STATS_END;
6610 *blob = p;
6611 *blob_size = sz;
6612 return RL2_OK;
6613 }
6614
6615 static int
check_raster_serialized_statistics(const unsigned char * blob,int blob_size)6616 check_raster_serialized_statistics (const unsigned char *blob, int blob_size)
6617 {
6618 /* checking a Raster Statistics serialized object from validity */
6619 const unsigned char *ptr = blob;
6620 int endian;
6621 uLong crc;
6622 uLong oldCrc;
6623 int ib;
6624 unsigned short nHistogram;
6625 unsigned char sample_type;
6626 unsigned char num_bands;
6627 int endian_arch = endianArch ();
6628
6629 if (blob == NULL)
6630 return 0;
6631 if (blob_size < 27)
6632 return 0;
6633 if (*ptr++ != 0x00)
6634 return 0; /* invalid start signature */
6635 if (*ptr++ != RL2_STATS_START)
6636 return 0; /* invalid start signature */
6637 endian = *ptr++;
6638 if (endian == RL2_LITTLE_ENDIAN || endian == RL2_BIG_ENDIAN)
6639 ;
6640 else
6641 return 0; /* invalid endiannes */
6642 sample_type = *ptr++;
6643 switch (sample_type)
6644 {
6645 case RL2_SAMPLE_1_BIT:
6646 case RL2_SAMPLE_2_BIT:
6647 case RL2_SAMPLE_4_BIT:
6648 case RL2_SAMPLE_INT8:
6649 case RL2_SAMPLE_UINT8:
6650 case RL2_SAMPLE_INT16:
6651 case RL2_SAMPLE_UINT16:
6652 case RL2_SAMPLE_INT32:
6653 case RL2_SAMPLE_UINT32:
6654 case RL2_SAMPLE_FLOAT:
6655 case RL2_SAMPLE_DOUBLE:
6656 break;
6657 default:
6658 return 0;
6659 };
6660 num_bands = *ptr++;
6661
6662 ptr = blob + 21;
6663 for (ib = 0; ib < num_bands; ib++)
6664 {
6665 if (((ptr - blob) + 38) >= blob_size)
6666 return 0;
6667 if (*ptr++ != RL2_BAND_STATS_START)
6668 return 0;
6669 ptr += 32;
6670 nHistogram = importU16 (ptr, endian, endian_arch);
6671 ptr += 2;
6672 if (*ptr++ != RL2_HISTOGRAM_START)
6673 return 0;
6674 if (((ptr - blob) + 2 + (nHistogram * sizeof (double))) >=
6675 (unsigned int) blob_size)
6676 return 0;
6677 ptr += nHistogram * sizeof (double);
6678 if (*ptr++ != RL2_HISTOGRAM_END)
6679 return 0;
6680 if (*ptr++ != RL2_BAND_STATS_END)
6681 return 0;
6682 }
6683 /* computing the CRC32 */
6684 crc = crc32 (0L, blob, ptr - blob);
6685 oldCrc = importU32 (ptr, endian, endian_arch);
6686 ptr += 4;
6687 if (crc != oldCrc)
6688 return 0;
6689 if (*ptr != RL2_STATS_END)
6690 return 0; /* invalid end signature */
6691
6692 return 1;
6693 }
6694
6695 RL2_DECLARE int
rl2_is_valid_dbms_raster_statistics(const unsigned char * blob,int blob_size,unsigned char sample_type,unsigned char num_bands)6696 rl2_is_valid_dbms_raster_statistics (const unsigned char *blob, int blob_size,
6697 unsigned char sample_type,
6698 unsigned char num_bands)
6699 {
6700 /* testing a serialized Raster Statistics object for validity */
6701 const unsigned char *ptr;
6702 unsigned char xsample_type;
6703 unsigned char xnum_bands;
6704 if (!check_raster_serialized_statistics (blob, blob_size))
6705 return RL2_ERROR;
6706 ptr = blob + 3;
6707 xsample_type = *ptr++;
6708 xnum_bands = *ptr++;
6709 if (sample_type == xsample_type && num_bands == xnum_bands)
6710 return RL2_OK;
6711 return RL2_ERROR;
6712 }
6713
6714 RL2_DECLARE rl2RasterStatisticsPtr
rl2_deserialize_dbms_raster_statistics(const unsigned char * blob,int blob_size)6715 rl2_deserialize_dbms_raster_statistics (const unsigned char *blob,
6716 int blob_size)
6717 {
6718 /* attempting to deserialize a Raster Statistics object from DBMS binary format */
6719 rl2RasterStatisticsPtr stats = NULL;
6720 rl2PrivRasterStatisticsPtr st;
6721 unsigned char sample_type;
6722 unsigned char num_bands;
6723 int ib;
6724 int ih;
6725 const unsigned char *ptr = blob;
6726 int endian;
6727 int endian_arch = endianArch ();
6728 if (!check_raster_serialized_statistics (blob, blob_size))
6729 return NULL;
6730
6731 ptr = blob + 2;
6732 endian = *ptr++;
6733 sample_type = *ptr++;
6734 num_bands = *ptr++;
6735 stats = rl2_create_raster_statistics (sample_type, num_bands);
6736 if (stats == NULL)
6737 goto error;
6738 st = (rl2PrivRasterStatisticsPtr) stats;
6739 st->no_data = importDouble (ptr, endian, endian_arch); /* # no_data values */
6740 ptr += 8;
6741 st->count = importDouble (ptr, endian, endian_arch); /* # count */
6742 ptr += 8;
6743 for (ib = 0; ib < num_bands; ib++)
6744 {
6745 rl2PrivBandStatisticsPtr band = st->band_stats + ib;
6746 ptr++; /* skipping BAND START marker */
6747 band->min = importDouble (ptr, endian, endian_arch); /* # Min values */
6748 ptr += 8;
6749 band->max = importDouble (ptr, endian, endian_arch); /* # Max values */
6750 ptr += 8;
6751 band->mean = importDouble (ptr, endian, endian_arch); /* # Mean */
6752 ptr += 8;
6753 band->sum_sq_diff = importDouble (ptr, endian, endian_arch); /* # Sum of square differences */
6754 ptr += 8;
6755 ptr += 3; /* skipping HISTOGRAM START marker */
6756 for (ih = 0; ih < band->nHistogram; ih++)
6757 {
6758 *(band->histogram + ih) = importDouble (ptr, endian, endian_arch); /* # Histogram values */
6759 ptr += 8;
6760 }
6761 ptr += 2; /* skipping END markers */
6762 }
6763 return stats;
6764
6765 error:
6766 if (stats != NULL)
6767 rl2_destroy_raster_statistics (stats);
6768 return NULL;
6769 }
6770
6771 RL2_DECLARE int
rl2_serialize_dbms_pixel(rl2PixelPtr pixel,unsigned char ** blob,int * blob_size)6772 rl2_serialize_dbms_pixel (rl2PixelPtr pixel, unsigned char **blob,
6773 int *blob_size)
6774 {
6775 /* creating a NO-DATA (DBMS serialized format) */
6776 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) pixel;
6777 rl2PrivSamplePtr band;
6778 int sz = 12;
6779 uLong crc;
6780 int ib;
6781 int endian_arch = endianArch ();
6782 unsigned char *p;
6783 unsigned char *ptr;
6784
6785 *blob = NULL;
6786 *blob_size = 0;
6787 if (pxl == NULL)
6788 return RL2_ERROR;
6789
6790 switch (pxl->sampleType)
6791 {
6792 case RL2_SAMPLE_1_BIT:
6793 case RL2_SAMPLE_2_BIT:
6794 case RL2_SAMPLE_4_BIT:
6795 case RL2_SAMPLE_INT8:
6796 sz += 3;
6797 break;
6798 case RL2_SAMPLE_UINT8:
6799 sz += pxl->nBands * 3;
6800 break;
6801 case RL2_SAMPLE_INT16:
6802 sz += 4;
6803 break;
6804 case RL2_SAMPLE_UINT16:
6805 sz += (pxl->nBands * 4);
6806 break;
6807 case RL2_SAMPLE_INT32:
6808 case RL2_SAMPLE_UINT32:
6809 case RL2_SAMPLE_FLOAT:
6810 sz += 6;
6811 break;
6812 case RL2_SAMPLE_DOUBLE:
6813 sz += 10;
6814 break;
6815 default:
6816 return RL2_ERROR;
6817 };
6818 p = malloc (sz);
6819 if (p == NULL)
6820 return RL2_ERROR;
6821 ptr = p;
6822
6823 *ptr++ = 0x00; /* start marker */
6824 *ptr++ = RL2_NO_DATA_START;
6825 *ptr++ = RL2_LITTLE_ENDIAN;
6826 *ptr++ = pxl->sampleType;
6827 *ptr++ = pxl->pixelType;
6828 *ptr++ = pxl->nBands;
6829 *ptr++ = pxl->isTransparent;
6830 for (ib = 0; ib < pxl->nBands; ib++)
6831 {
6832 *ptr++ = RL2_SAMPLE_START;
6833 band = pxl->Samples + ib;
6834 switch (pxl->sampleType)
6835 {
6836 case RL2_SAMPLE_INT8:
6837 *ptr++ = (unsigned char) (band->int8);
6838 break;
6839 case RL2_SAMPLE_1_BIT:
6840 case RL2_SAMPLE_2_BIT:
6841 case RL2_SAMPLE_4_BIT:
6842 case RL2_SAMPLE_UINT8:
6843 *ptr++ = band->uint8;
6844 break;
6845 case RL2_SAMPLE_INT16:
6846 export16 (ptr, band->int16, 1, endian_arch);
6847 ptr += 2;
6848 break;
6849 case RL2_SAMPLE_UINT16:
6850 exportU16 (ptr, band->uint16, 1, endian_arch);
6851 ptr += 2;
6852 break;
6853 case RL2_SAMPLE_INT32:
6854 export32 (ptr, band->int32, 1, endian_arch);
6855 ptr += 4;
6856 break;
6857 case RL2_SAMPLE_UINT32:
6858 exportU32 (ptr, band->uint32, 1, endian_arch);
6859 ptr += 4;
6860 break;
6861 case RL2_SAMPLE_FLOAT:
6862 exportFloat (ptr, band->float32, 1, endian_arch);
6863 ptr += 4;
6864 break;
6865 case RL2_SAMPLE_DOUBLE:
6866 exportDouble (ptr, band->float64, 1, endian_arch);
6867 ptr += 8;
6868 break;
6869 };
6870 *ptr++ = RL2_SAMPLE_END;
6871 }
6872 /* computing the CRC32 */
6873 crc = crc32 (0L, p, ptr - p);
6874 exportU32 (ptr, crc, 1, endian_arch); /* the NO-DATA own CRC */
6875 ptr += 4;
6876 *ptr++ = RL2_NO_DATA_END;
6877 *blob = p;
6878 *blob_size = sz;
6879 return RL2_OK;
6880 }
6881
6882 static int
check_raster_serialized_pixel(const unsigned char * blob,int blob_size)6883 check_raster_serialized_pixel (const unsigned char *blob, int blob_size)
6884 {
6885 /* checking a Pixel value serialized object from validity */
6886 const unsigned char *ptr = blob;
6887 int endian;
6888 uLong crc;
6889 uLong oldCrc;
6890 int ib;
6891 unsigned char sample_type;
6892 unsigned char pixel_type;
6893 unsigned char num_bands;
6894 int endian_arch = endianArch ();
6895
6896 if (blob == NULL)
6897 return 0;
6898 if (blob_size < 13)
6899 return 0;
6900 if (*ptr++ != 0x00)
6901 return 0; /* invalid start signature */
6902 if (*ptr++ != RL2_NO_DATA_START)
6903 return 0; /* invalid start signature */
6904 endian = *ptr++;
6905 if (endian == RL2_LITTLE_ENDIAN || endian == RL2_BIG_ENDIAN)
6906 ;
6907 else
6908 return 0; /* invalid endiannes */
6909 sample_type = *ptr++;
6910 switch (sample_type)
6911 {
6912 case RL2_SAMPLE_1_BIT:
6913 case RL2_SAMPLE_2_BIT:
6914 case RL2_SAMPLE_4_BIT:
6915 case RL2_SAMPLE_INT8:
6916 case RL2_SAMPLE_UINT8:
6917 case RL2_SAMPLE_INT16:
6918 case RL2_SAMPLE_UINT16:
6919 case RL2_SAMPLE_INT32:
6920 case RL2_SAMPLE_UINT32:
6921 case RL2_SAMPLE_FLOAT:
6922 case RL2_SAMPLE_DOUBLE:
6923 break;
6924 default:
6925 return 0;
6926 };
6927 pixel_type = *ptr++;
6928 switch (pixel_type)
6929 {
6930 case RL2_PIXEL_MONOCHROME:
6931 case RL2_PIXEL_PALETTE:
6932 case RL2_PIXEL_GRAYSCALE:
6933 case RL2_PIXEL_RGB:
6934 case RL2_PIXEL_MULTIBAND:
6935 case RL2_PIXEL_DATAGRID:
6936 break;
6937 default:
6938 return 0;
6939 };
6940 num_bands = *ptr++;
6941 ptr++;
6942 switch (sample_type)
6943 {
6944 case RL2_SAMPLE_1_BIT:
6945 if ((pixel_type == RL2_PIXEL_PALETTE
6946 || pixel_type == RL2_PIXEL_MONOCHROME) && num_bands == 1)
6947 ;
6948 else
6949 return 0;
6950 break;
6951 case RL2_SAMPLE_2_BIT:
6952 case RL2_SAMPLE_4_BIT:
6953 if ((pixel_type == RL2_PIXEL_PALETTE
6954 || pixel_type == RL2_PIXEL_GRAYSCALE) && num_bands == 1)
6955 ;
6956 else
6957 return 0;
6958 break;
6959 case RL2_SAMPLE_UINT8:
6960 if ((pixel_type == RL2_PIXEL_PALETTE
6961 || pixel_type == RL2_PIXEL_GRAYSCALE
6962 || pixel_type == RL2_PIXEL_DATAGRID) && num_bands == 1)
6963 ;
6964 else if (pixel_type == RL2_PIXEL_RGB && num_bands == 3)
6965 ;
6966 else if (pixel_type == RL2_PIXEL_MULTIBAND && num_bands > 1)
6967 ;
6968 else
6969 return 0;
6970 break;
6971 case RL2_SAMPLE_UINT16:
6972 if ((pixel_type == RL2_PIXEL_GRAYSCALE
6973 || pixel_type == RL2_PIXEL_DATAGRID) && num_bands == 1)
6974 ;
6975 else if (pixel_type == RL2_PIXEL_RGB && num_bands == 3)
6976 ;
6977 else if (pixel_type == RL2_PIXEL_MULTIBAND && num_bands > 1)
6978 ;
6979 else
6980 return 0;
6981 break;
6982 case RL2_SAMPLE_INT8:
6983 case RL2_SAMPLE_INT16:
6984 case RL2_SAMPLE_INT32:
6985 case RL2_SAMPLE_UINT32:
6986 case RL2_SAMPLE_FLOAT:
6987 case RL2_SAMPLE_DOUBLE:
6988 if (pixel_type == RL2_PIXEL_DATAGRID && num_bands == 1)
6989 ;
6990 else
6991 return 0;
6992 break;
6993 default:
6994 return 0;
6995 };
6996
6997 for (ib = 0; ib < num_bands; ib++)
6998 {
6999 if (*ptr++ != RL2_SAMPLE_START)
7000 return 0;
7001 switch (sample_type)
7002 {
7003 case RL2_SAMPLE_1_BIT:
7004 case RL2_SAMPLE_2_BIT:
7005 case RL2_SAMPLE_4_BIT:
7006 case RL2_SAMPLE_INT8:
7007 case RL2_SAMPLE_UINT8:
7008 ptr++;
7009 break;
7010 case RL2_SAMPLE_INT16:
7011 case RL2_SAMPLE_UINT16:
7012 ptr += 2;
7013 break;
7014 case RL2_SAMPLE_INT32:
7015 case RL2_SAMPLE_UINT32:
7016 case RL2_SAMPLE_FLOAT:
7017 ptr += 4;
7018 break;
7019 case RL2_SAMPLE_DOUBLE:
7020 ptr += 8;
7021 break;
7022 };
7023 if (((ptr - blob) + 6) > blob_size)
7024 return 0;
7025 if (*ptr++ != RL2_SAMPLE_END)
7026 return 0;
7027 }
7028 /* computing the CRC32 */
7029 crc = crc32 (0L, blob, ptr - blob);
7030 oldCrc = importU32 (ptr, endian, endian_arch);
7031 ptr += 4;
7032 if (crc != oldCrc)
7033 return 0;
7034 if (*ptr != RL2_NO_DATA_END)
7035 return 0; /* invalid end signature */
7036
7037 return 1;
7038 }
7039
7040 RL2_DECLARE int
rl2_is_valid_dbms_pixel(const unsigned char * blob,int blob_size,unsigned char sample_type,unsigned char num_bands)7041 rl2_is_valid_dbms_pixel (const unsigned char *blob, int blob_size,
7042 unsigned char sample_type, unsigned char num_bands)
7043 {
7044 /* testing a serialized Pixel value for validity */
7045 const unsigned char *ptr;
7046 unsigned char xsample_type;
7047 unsigned char xnum_bands;
7048 if (!check_raster_serialized_pixel (blob, blob_size))
7049 return RL2_ERROR;
7050 ptr = blob + 3;
7051 xsample_type = *ptr++;
7052 ptr++;
7053 xnum_bands = *ptr++;
7054 if (sample_type == xsample_type && num_bands == xnum_bands)
7055 return RL2_OK;
7056 return RL2_ERROR;
7057 }
7058
7059 RL2_DECLARE rl2PixelPtr
rl2_deserialize_dbms_pixel(const unsigned char * blob,int blob_size)7060 rl2_deserialize_dbms_pixel (const unsigned char *blob, int blob_size)
7061 {
7062 /* attempting to deserialize a Pixel value from DBMS binary format */
7063 rl2PixelPtr pixel = NULL;
7064 rl2PrivPixelPtr pxl;
7065 unsigned char sample_type;
7066 unsigned char pixel_type;
7067 unsigned char num_bands;
7068 unsigned char transparent;
7069 int ib;
7070 const unsigned char *ptr = blob;
7071 int endian;
7072 int endian_arch = endianArch ();
7073 if (!check_raster_serialized_pixel (blob, blob_size))
7074 return NULL;
7075
7076 ptr = blob + 2;
7077 endian = *ptr++;
7078 sample_type = *ptr++;
7079 pixel_type = *ptr++;
7080 num_bands = *ptr++;
7081 transparent = *ptr++;
7082 pixel = rl2_create_pixel (sample_type, pixel_type, num_bands);
7083 if (pixel == NULL)
7084 goto error;
7085 pxl = (rl2PrivPixelPtr) pixel;
7086 pxl->isTransparent = transparent;
7087 for (ib = 0; ib < num_bands; ib++)
7088 {
7089 rl2PrivSamplePtr band = pxl->Samples + ib;
7090 ptr++; /* skipping SAMPLE START marker */
7091 switch (sample_type)
7092 {
7093 case RL2_SAMPLE_INT8:
7094 band->int8 = *((char *) ptr);
7095 ptr++;
7096 break;
7097 case RL2_SAMPLE_1_BIT:
7098 case RL2_SAMPLE_2_BIT:
7099 case RL2_SAMPLE_4_BIT:
7100 case RL2_SAMPLE_UINT8:
7101 band->uint8 = *ptr;
7102 ptr++;
7103 break;
7104 case RL2_SAMPLE_INT16:
7105 band->int16 = import16 (ptr, endian, endian_arch);
7106 ptr += 2;
7107 break;
7108 case RL2_SAMPLE_UINT16:
7109 band->uint16 = importU16 (ptr, endian, endian_arch);
7110 ptr += 2;
7111 break;
7112 case RL2_SAMPLE_INT32:
7113 band->int32 = import32 (ptr, endian, endian_arch);
7114 ptr += 4;
7115 break;
7116 case RL2_SAMPLE_UINT32:
7117 band->uint32 = importU32 (ptr, endian, endian_arch);
7118 ptr += 4;
7119 break;
7120 case RL2_SAMPLE_FLOAT:
7121 band->float32 = importFloat (ptr, endian, endian_arch);
7122 ptr += 4;
7123 break;
7124 case RL2_SAMPLE_DOUBLE:
7125 band->float64 = importDouble (ptr, endian, endian_arch);
7126 ptr += 8;
7127 break;
7128 };
7129 ptr++; /* skipping SAMPLE END marker */
7130 }
7131 return pixel;
7132
7133 error:
7134 if (pixel != NULL)
7135 rl2_destroy_pixel (pixel);
7136 return NULL;
7137 }
7138