Dali 3D User Interface Engine
data-compression.cpp
Go to the documentation of this file.
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
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" );
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");
144  return false;
145  }
146 
147  return true;
148 }
149 
150 } // DataCompression
151 
152 } // namespace TizenPlatform
153 
154 } // namespace Dali
Dali Docs Home
Read more about Dali