1 /*
2 ===============================================================================
3 
4   PROGRAMMERS:
5 
6     martin.isenburg@rapidlasso.com  -  http://rapidlasso.com
7     uday.karan@gmail.com - Hobu, Inc.
8     andrew.bell.ia@gmail.com - Hobu Inc.
9 
10   COPYRIGHT:
11 
12     (c) 2007-2014, martin isenburg, rapidlasso - tools to catch reality
13     (c) 2014, Uday Verma, Hobu, Inc.
14 
15     This is free software; you can redistribute and/or modify it under the
16     terms of the GNU Lesser General Licence as published by the Free Software
17     Foundation. See the COPYING file for more information.
18 
19     This software is distributed WITHOUT ANY WARRANTY and without even the
20     implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 
22   CHANGE HISTORY:
23 
24 ===============================================================================
25 */
26 
27 #include "../las.hpp"
28 
29 #include <deque>
30 
31 namespace lazperf
32 {
33 namespace detail
34 {
35 
Byte10Base(size_t count)36 Byte10Base::Byte10Base(size_t count) : count_(count), have_last_(false),
37     lasts_(count), diffs_(count), models_(count, models::arithmetic(256))
38 {}
39 
40 // COMPRESSOR
41 
Byte10Compressor(encoders::arithmetic<OutCbStream> & encoder,size_t count)42 Byte10Compressor::Byte10Compressor(encoders::arithmetic<OutCbStream>& encoder, size_t count) :
43     Byte10Base(count), enc_(encoder)
44 {}
45 
compress(const char * buf)46 const char *Byte10Compressor::compress(const char *buf)
47 {
48     if (count_ == 0)
49         return buf;
50 
51     auto li = lasts_.begin();
52     auto di = diffs_.begin();
53     while (di != diffs_.end())
54     {
55         *di = *buf - *li;
56         *li = *buf;
57         di++; buf++; li++;
58     }
59 
60     if (!have_last_)
61     {
62         enc_.getOutStream().putBytes(lasts_.data(), count_);
63         have_last_ = true;
64     }
65     else
66     {
67         di = diffs_.begin();
68         auto mi = models_.begin();
69         while (di != diffs_.end())
70             enc_.encodeSymbol(*mi++, *di++);
71     }
72     return buf;
73 }
74 
75 // DECOMPRESSOR
76 
Byte10Decompressor(decoders::arithmetic<InCbStream> & decoder,size_t count)77 Byte10Decompressor::Byte10Decompressor(decoders::arithmetic<InCbStream>& decoder, size_t count) :
78     Byte10Base(count), dec_(decoder)
79 {}
80 
decompress(char * buf)81 char *Byte10Decompressor::decompress(char *buf)
82 {
83     if (count_ == 0)
84         return buf;
85 
86     if (!have_last_)
87     {
88         dec_.getInStream().getBytes((unsigned char *)buf, count_);
89         std::copy(buf, buf + count_, lasts_.data());
90         have_last_ = true;
91         return buf + count_;
92     }
93     // Use the diff vector for our current values.
94     auto& curs = diffs_;
95     auto ci = curs.begin();
96     auto li = lasts_.begin();
97     auto mi = models_.begin();
98     while (li != lasts_.end())
99     {
100         *ci = (uint8_t)(*li + dec_.decodeSymbol(*mi));
101         *li = *buf = *ci;
102         li++; buf++; ci++; mi++;
103     }
104     return buf;
105 }
106 
107 } // namespace detail
108 } // namespace lazperf
109