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