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
29 std::size_t GetMaximumRleCompressedSize(const std::size_t inputLength)
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
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
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 :
49 // First 4 bytes are the size of the decoded data
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)
57 DALI_ASSERT_DEBUG( outputLength >= GetMaximumRleCompressedSize( inputLength ));
59 unsigned int index(0);
60 unsigned int runLength(0);
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;
69 while( index < inputLength )
71 unsigned char curChar = input[ index ];
74 if( ( (index + 1) == inputLength ) // is more data available
75 || input[index + 1] != curChar ) // character doesn't match
77 // we out of data, or the next character doesn't match (run of zero)
82 while( ( (index+1) < inputLength ) &&
83 ( input[index + 1] == curChar ) &&
84 ( runLength < 0xFF ) )
91 output[ encodedSize++ ] = runLength;
92 output[ encodedSize++ ] = curChar;
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)
103 unsigned int index(0);
104 unsigned int outputIndex(0);
106 // there should be at least 4 bytes for the size field
109 DALI_LOG_ERROR("input buffer too small\n");
113 decodedSize = input[ index++ ] ;
114 decodedSize|= input[ index++ ]<<8 ;
115 decodedSize|= input[ index++ ]<<16 ;
116 decodedSize|= input[ index++ ]<<24 ;
118 // check the decoded data will fit in to
119 if( outputLength < decodedSize )
121 DALI_LOG_ERROR("buffer too small, buffer size =%d, data size = %d \n",outputLength, decodedSize);
125 while( (index+1)< inputLength )
127 // read the value and the run length
128 unsigned char runLength = input[ index++ ];
129 unsigned char value = input[ index++ ];
131 if( (runLength + outputIndex) > decodedSize)
133 DALI_LOG_ERROR( "corrupted RLE data\n" );
137 // set the value run Length times
138 memset( &output[ outputIndex ], value, runLength * sizeof( unsigned char) );
139 outputIndex+= runLength;
141 if( outputIndex != decodedSize)
143 DALI_LOG_ERROR(" RLE data size missmatch\n");
152 } // namespace TizenPlatform