Merge "Make another ConditionalWait for post-rendearing" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / legacy / tizen / 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 std::size_t GetMaximumRleCompressedSize(const std::size_t inputLength)
29 {
30   // RLE has worst case scenerio of double the input data
31   // e.g. if data is 1,2,3,4  = 4 bytes
32   // it will be encoded as 1,1, 1,2 1,3 1,4 = 8 bytes
33
34   // we also encode the original size into the stream to check
35   // the decode buffers are big enough and for corruption
36   return (inputLength * 2) + 4; // 4 bytes is space for size
37 }
38
39 // Run length encode a byte stream, consisting of byte values.
40 // Format is one byte for run-length, one byte value.
41 // e.g. 10, 15, 20, 20, 20, 5, 5
42 // is represented as :
43 // 1,10
44 // 1,15
45 // 3,20
46 // 2, 5
47 // First 4 bytes are the size of the decoded data
48 //
49 void EncodeRle(const unsigned char* input,
50                const std::size_t    inputLength,
51                unsigned char*       output,
52                const std::size_t    outputLength,
53                std::size_t&         encodedSize)
54 {
55   DALI_ASSERT_DEBUG(outputLength >= GetMaximumRleCompressedSize(inputLength));
56
57   unsigned int index(0);
58   unsigned int runLength(0);
59   encodedSize = 0;
60
61   // encode the input length in the first 4 bytes.
62   output[encodedSize++] = inputLength & 0xFF;
63   output[encodedSize++] = (inputLength >> 8) & 0xFF;
64   output[encodedSize++] = (inputLength >> 16) & 0xFF;
65   output[encodedSize++] = (inputLength >> 24) & 0xFF;
66
67   while(index < inputLength)
68   {
69     unsigned char curChar = input[index];
70     runLength             = 1;
71
72     if(((index + 1) == inputLength)    // is more data available
73        || input[index + 1] != curChar) // character doesn't match
74     {
75       // we out of data, or the next character doesn't match (run of zero)
76       index++;
77     }
78     else
79     {
80       while(((index + 1) < inputLength) &&
81             (input[index + 1] == curChar) &&
82             (runLength < 0xFF))
83       {
84         runLength++;
85         index++;
86       }
87       index++;
88     }
89     output[encodedSize++] = runLength;
90     output[encodedSize++] = curChar;
91   }
92 }
93
94 bool DecodeRle(const unsigned char* input,
95                const std::size_t    inputLength,
96                unsigned char*       output,
97                const std::size_t    outputLength,
98                std::size_t&         decodedSize)
99 {
100   unsigned int index(0);
101   unsigned int outputIndex(0);
102
103   // there should be at least 4 bytes for the size field
104   if(inputLength < 4)
105   {
106     DALI_LOG_ERROR("input buffer too small\n");
107     return false;
108   }
109
110   decodedSize = input[index++];
111   decodedSize |= input[index++] << 8;
112   decodedSize |= input[index++] << 16;
113   decodedSize |= input[index++] << 24;
114
115   // check the decoded data will fit in to
116   if(outputLength < decodedSize)
117   {
118     DALI_LOG_ERROR("buffer too small, buffer size =%d, data size = %d \n", outputLength, decodedSize);
119     return false;
120   }
121
122   while((index + 1) < inputLength)
123   {
124     // read the value and the run length
125     unsigned char runLength = input[index++];
126     unsigned char value     = input[index++];
127
128     if((runLength + outputIndex) > decodedSize)
129     {
130       DALI_LOG_ERROR("corrupted RLE data\n");
131       // corrupted
132       return false;
133     }
134     // set the value run Length times
135     memset(&output[outputIndex], value, runLength * sizeof(unsigned char));
136     outputIndex += runLength;
137   }
138   if(outputIndex != decodedSize)
139   {
140     DALI_LOG_ERROR(" RLE data size missmatch\n");
141     return false;
142   }
143
144   return true;
145 }
146
147 } // namespace DataCompression
148
149 } // namespace TizenPlatform
150
151 } // namespace Dali