Merge "Set proper locale to harfbuzz" into devel/master
[platform/core/uifw/dali-adaptor.git] / platform-abstractions / tizen / data-cache / data-compression.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // INTERNAL INCLUDES
19 #include <dali/integration-api/debug.h>
20 #include <memory.h>
21
22 namespace Dali
23 {
24 namespace TizenPlatform
25 {
26 namespace DataCompression
27 {
28
29 std::size_t GetMaximumRleCompressedSize(const std::size_t inputLength)
30 {
31   // RLE has worst case scenerio of double the input data
32   // e.g. if data is 1,2,3,4  = 4 bytes
33   // it will be encoded as 1,1, 1,2 1,3 1,4 = 8 bytes
34
35   // we also encode the original size into the stream to check
36   // the decode buffers are big enough and for corruption
37   return (inputLength * 2) + 4;  // 4 bytes is space for size
38
39 }
40
41 // Run length encode a byte stream, consisting of byte values.
42 // Format is one byte for run-length, one byte value.
43 // e.g. 10, 15, 20, 20, 20, 5, 5
44 // is represented as :
45 // 1,10
46 // 1,15
47 // 3,20
48 // 2, 5
49 // First 4 bytes are the size of the decoded data
50 //
51 void EncodeRle( const unsigned char* input,
52                 const std::size_t inputLength,
53                 unsigned char* output,
54                 const std::size_t outputLength,
55                 std::size_t& encodedSize)
56 {
57   DALI_ASSERT_DEBUG( outputLength >= GetMaximumRleCompressedSize( inputLength ));
58
59   unsigned int index(0);
60   unsigned int runLength(0);
61   encodedSize = 0;
62
63   // encode the input length in the first 4 bytes.
64   output[ encodedSize++ ] =  inputLength & 0xFF;
65   output[ encodedSize++ ] = (inputLength >> 8) & 0xFF;
66   output[ encodedSize++ ] = (inputLength >> 16) & 0xFF;
67   output[ encodedSize++ ] = (inputLength >> 24) & 0xFF;
68
69   while( index < inputLength  )
70   {
71     unsigned char curChar = input[ index ];
72     runLength = 1;
73
74     if( ( (index + 1) == inputLength )         // is more data available
75         || input[index + 1] != curChar  )      // character doesn't match
76     {
77       // we out of data, or the next character doesn't match (run of zero)
78       index++;
79     }
80     else
81     {
82       while( ( (index+1) < inputLength ) &&
83                ( input[index + 1] == curChar ) &&
84                ( runLength < 0xFF ) )
85       {
86         runLength++;
87         index++;
88       }
89       index++;
90     }
91     output[ encodedSize++ ] = runLength;
92     output[ encodedSize++ ] = curChar;
93
94   }
95 }
96
97 bool DecodeRle( const unsigned char* input,
98                 const std::size_t inputLength,
99                 unsigned char* output,
100                 const std::size_t outputLength,
101                 std::size_t& decodedSize)
102 {
103   unsigned int index(0);
104   unsigned int outputIndex(0);
105
106   // there should be at least 4 bytes for the size field
107   if( inputLength < 4)
108   {
109     DALI_LOG_ERROR("input buffer too small\n");
110     return false;
111   }
112
113   decodedSize = input[ index++ ] ;
114   decodedSize|= input[ index++ ]<<8 ;
115   decodedSize|= input[ index++ ]<<16 ;
116   decodedSize|= input[ index++ ]<<24 ;
117
118   // check the decoded data will fit in to
119   if( outputLength < decodedSize )
120   {
121     DALI_LOG_ERROR("buffer too small, buffer size =%d, data size = %d \n",outputLength, decodedSize);
122     return false;
123   }
124
125   while( (index+1)< inputLength )
126   {
127     // read the value and the run length
128     unsigned char runLength =  input[ index++ ];
129     unsigned char value = input[ index++ ];
130
131     if( (runLength + outputIndex) > decodedSize)
132     {
133       DALI_LOG_ERROR( "corrupted RLE data\n" );
134       // corrupted
135       return false;
136     }
137     // set the value run Length times
138     memset( &output[ outputIndex ], value, runLength * sizeof( unsigned char) );
139     outputIndex+= runLength;
140   }
141   if( outputIndex != decodedSize)
142   {
143     DALI_LOG_ERROR(" RLE data size missmatch\n");
144     return false;
145   }
146
147   return true;
148 }
149
150 } // DataCompression
151
152 } // namespace TizenPlatform
153
154 } // namespace Dali