2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/integration-api/debug.h>
24 namespace TizenPlatform
26 namespace DataCompression
28 std::size_t GetMaximumRleCompressedSize(const std::size_t inputLength)
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
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
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 :
47 // First 4 bytes are the size of the decoded data
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)
55 DALI_ASSERT_DEBUG(outputLength >= GetMaximumRleCompressedSize(inputLength));
57 unsigned int index(0);
58 unsigned int runLength(0);
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;
67 while(index < inputLength)
69 unsigned char curChar = input[index];
72 if(((index + 1) == inputLength) // is more data available
73 || input[index + 1] != curChar) // character doesn't match
75 // we out of data, or the next character doesn't match (run of zero)
80 while(((index + 1) < inputLength) &&
81 (input[index + 1] == curChar) &&
89 output[encodedSize++] = runLength;
90 output[encodedSize++] = curChar;
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)
100 unsigned int index(0);
101 unsigned int outputIndex(0);
103 // there should be at least 4 bytes for the size field
106 DALI_LOG_ERROR("input buffer too small\n");
110 decodedSize = input[index++];
111 decodedSize |= input[index++] << 8;
112 decodedSize |= input[index++] << 16;
113 decodedSize |= input[index++] << 24;
115 // check the decoded data will fit in to
116 if(outputLength < decodedSize)
118 DALI_LOG_ERROR("buffer too small, buffer size =%d, data size = %d \n", outputLength, decodedSize);
122 while((index + 1) < inputLength)
124 // read the value and the run length
125 unsigned char runLength = input[index++];
126 unsigned char value = input[index++];
128 if((runLength + outputIndex) > decodedSize)
130 DALI_LOG_ERROR("corrupted RLE data\n");
134 // set the value run Length times
135 memset(&output[outputIndex], value, runLength * sizeof(unsigned char));
136 outputIndex += runLength;
138 if(outputIndex != decodedSize)
140 DALI_LOG_ERROR(" RLE data size missmatch\n");
147 } // namespace DataCompression
149 } // namespace TizenPlatform