annotate ezBAMQC/src/htslib/cram/rANS_static.c @ 15:28cebcc7f774

Uploaded
author cshl-bsr
date Wed, 30 Mar 2016 12:15:18 -0400
parents dfa3745e5fd8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
1 /*
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
2 * Copyright (c) 2014 Genome Research Ltd.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
3 * Author(s): James Bonfield
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
4 *
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
5 * Redistribution and use in source and binary forms, with or without
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
6 * modification, are permitted provided that the following conditions are met:
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
7 *
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
8 * 1. Redistributions of source code must retain the above copyright notice,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
9 * this list of conditions and the following disclaimer.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
10 *
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
11 * 2. Redistributions in binary form must reproduce the above
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
12 * copyright notice, this list of conditions and the following
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
13 * disclaimer in the documentation and/or other materials provided
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
14 * with the distribution.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
15 *
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
16 * 3. Neither the names Genome Research Ltd and Wellcome Trust Sanger
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
17 * Institute nor the names of its contributors may be used to endorse
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
18 * or promote products derived from this software without specific
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
19 * prior written permission.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
20 *
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
21 * THIS SOFTWARE IS PROVIDED BY GENOME RESEARCH LTD AND CONTRIBUTORS "AS
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENOME RESEARCH
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
25 * LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
32 */
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
33
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
34 /*
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
35 * Author: James Bonfield, Wellcome Trust Sanger Institute. 2014
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
36 */
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
37
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
38 #include <stdint.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
39 #include <stdlib.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
40 #include <stdio.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
41 #include <unistd.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
42 #include <assert.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
43 #include <string.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
44 #include <sys/time.h>
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
45
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
46 #include "cram/rANS_static.h"
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
47 #include "cram/rANS_byte.h"
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
48
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
49 #define TF_SHIFT 12
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
50 #define TOTFREQ (1<<TF_SHIFT)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
51
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
52 #define ABS(a) ((a)>0?(a):-(a))
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
53 #ifndef BLK_SIZE
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
54 # define BLK_SIZE 1024*1024
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
55 #endif
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
56
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
57 // Room to allow for expanded BLK_SIZE on worst case compression.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
58 #define BLK_SIZE2 ((int)(1.05*BLK_SIZE))
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
59
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
60 /*-----------------------------------------------------------------------------
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
61 * Memory to memory compression functions.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
62 *
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
63 * These are original versions without any manual loop unrolling. They
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
64 * are easier to understand, but can be up to 2x slower.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
65 */
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
66
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
67 unsigned char *rans_compress_O0(unsigned char *in, unsigned int in_size,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
68 unsigned int *out_size) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
69 unsigned char *out_buf = malloc(1.05*in_size + 257*257*3 + 9);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
70 unsigned char *cp, *out_end;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
71 RansEncSymbol syms[256];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
72 RansState rans0, rans1, rans2, rans3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
73 uint8_t* ptr;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
74 int F[256] = {0}, i, j, tab_size, rle, x, fsum = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
75 int m = 0, M = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
76 uint64_t tr;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
77
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
78 if (!out_buf)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
79 return NULL;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
80
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
81 ptr = out_end = out_buf + (int)(1.05*in_size) + 257*257*3 + 9;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
82
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
83 // Compute statistics
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
84 for (i = 0; i < in_size; i++) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
85 F[in[i]]++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
86 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
87 tr = ((uint64_t)TOTFREQ<<31)/in_size + (1<<30)/in_size;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
88
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
89 // Normalise so T[i] == TOTFREQ
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
90 for (m = M = j = 0; j < 256; j++) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
91 if (!F[j])
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
92 continue;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
93
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
94 if (m < F[j])
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
95 m = F[j], M = j;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
96
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
97 if ((F[j] = (F[j]*tr)>>31) == 0)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
98 F[j] = 1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
99 fsum += F[j];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
100 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
101
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
102 fsum++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
103 if (fsum < TOTFREQ)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
104 F[M] += TOTFREQ-fsum;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
105 else
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
106 F[M] -= fsum-TOTFREQ;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
107
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
108 //printf("F[%d]=%d\n", M, F[M]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
109 assert(F[M]>0);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
110
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
111 // Encode statistics.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
112 cp = out_buf+9;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
113
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
114 for (x = rle = j = 0; j < 256; j++) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
115 if (F[j]) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
116 // j
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
117 if (rle) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
118 rle--;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
119 } else {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
120 *cp++ = j;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
121 if (!rle && j && F[j-1]) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
122 for(rle=j+1; rle<256 && F[rle]; rle++)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
123 ;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
124 rle -= j+1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
125 *cp++ = rle;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
126 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
127 //fprintf(stderr, "%d: %d %d\n", j, rle, N[j]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
128 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
129
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
130 // F[j]
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
131 if (F[j]<128) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
132 *cp++ = F[j];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
133 } else {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
134 *cp++ = 128 | (F[j]>>8);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
135 *cp++ = F[j]&0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
136 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
137 RansEncSymbolInit(&syms[j], x, F[j], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
138 x += F[j];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
139 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
140 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
141 *cp++ = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
142
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
143 //write(1, out_buf+4, cp-(out_buf+4));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
144 tab_size = cp-out_buf;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
145
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
146 RansEncInit(&rans0);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
147 RansEncInit(&rans1);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
148 RansEncInit(&rans2);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
149 RansEncInit(&rans3);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
150
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
151 switch (i=(in_size&3)) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
152 case 3: RansEncPutSymbol(&rans2, &ptr, &syms[in[in_size-(i-2)]]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
153 case 2: RansEncPutSymbol(&rans1, &ptr, &syms[in[in_size-(i-1)]]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
154 case 1: RansEncPutSymbol(&rans0, &ptr, &syms[in[in_size-(i-0)]]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
155 case 0:
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
156 break;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
157 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
158 for (i=(in_size &~3); i>0; i-=4) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
159 RansEncSymbol *s3 = &syms[in[i-1]];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
160 RansEncSymbol *s2 = &syms[in[i-2]];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
161 RansEncSymbol *s1 = &syms[in[i-3]];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
162 RansEncSymbol *s0 = &syms[in[i-4]];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
163
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
164 RansEncPutSymbol(&rans3, &ptr, s3);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
165 RansEncPutSymbol(&rans2, &ptr, s2);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
166 RansEncPutSymbol(&rans1, &ptr, s1);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
167 RansEncPutSymbol(&rans0, &ptr, s0);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
168 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
169
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
170 RansEncFlush(&rans3, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
171 RansEncFlush(&rans2, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
172 RansEncFlush(&rans1, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
173 RansEncFlush(&rans0, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
174
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
175 // Finalise block size and return it
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
176 *out_size = (out_end - ptr) + tab_size;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
177
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
178 cp = out_buf;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
179
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
180 *cp++ = 0; // order
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
181 *cp++ = ((*out_size-9)>> 0) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
182 *cp++ = ((*out_size-9)>> 8) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
183 *cp++ = ((*out_size-9)>>16) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
184 *cp++ = ((*out_size-9)>>24) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
185
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
186 *cp++ = (in_size>> 0) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
187 *cp++ = (in_size>> 8) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
188 *cp++ = (in_size>>16) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
189 *cp++ = (in_size>>24) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
190
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
191 memmove(out_buf + tab_size, ptr, out_end-ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
192
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
193 return out_buf;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
194 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
195
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
196 typedef struct {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
197 struct {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
198 int F;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
199 int C;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
200 } fc[256];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
201 unsigned char *R;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
202 } ari_decoder;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
203
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
204 unsigned char *rans_uncompress_O0(unsigned char *in, unsigned int in_size,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
205 unsigned int *out_size) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
206 /* Load in the static tables */
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
207 unsigned char *cp = in + 9;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
208 int i, j, x, out_sz, in_sz, rle;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
209 char *out_buf;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
210 ari_decoder D;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
211 RansDecSymbol syms[256];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
212
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
213 memset(&D, 0, sizeof(D));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
214
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
215 if (*in++ != 0) // Order-0 check
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
216 return NULL;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
217
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
218 in_sz = ((in[0])<<0) | ((in[1])<<8) | ((in[2])<<16) | ((in[3])<<24);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
219 out_sz = ((in[4])<<0) | ((in[5])<<8) | ((in[6])<<16) | ((in[7])<<24);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
220 if (in_sz != in_size-9)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
221 return NULL;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
222
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
223 out_buf = malloc(out_sz);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
224 if (!out_buf)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
225 return NULL;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
226
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
227 //fprintf(stderr, "out_sz=%d\n", out_sz);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
228
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
229 // Precompute reverse lookup of frequency.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
230 rle = x = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
231 j = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
232 do {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
233 if ((D.fc[j].F = *cp++) >= 128) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
234 D.fc[j].F &= ~128;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
235 D.fc[j].F = ((D.fc[j].F & 127) << 8) | *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
236 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
237 D.fc[j].C = x;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
238
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
239 RansDecSymbolInit(&syms[j], D.fc[j].C, D.fc[j].F);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
240
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
241 /* Build reverse lookup table */
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
242 if (!D.R) D.R = (unsigned char *)malloc(TOTFREQ);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
243 memset(&D.R[x], j, D.fc[j].F);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
244
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
245 x += D.fc[j].F;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
246
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
247 if (!rle && j+1 == *cp) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
248 j = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
249 rle = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
250 } else if (rle) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
251 rle--;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
252 j++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
253 } else {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
254 j = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
255 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
256 } while(j);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
257
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
258 assert(x < TOTFREQ);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
259
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
260 RansState rans0, rans1, rans2, rans3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
261 uint8_t *ptr = cp;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
262 RansDecInit(&rans0, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
263 RansDecInit(&rans1, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
264 RansDecInit(&rans2, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
265 RansDecInit(&rans3, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
266
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
267 int out_end = (out_sz&~3);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
268
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
269 RansState R[4];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
270 R[0] = rans0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
271 R[1] = rans1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
272 R[2] = rans2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
273 R[3] = rans3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
274 uint32_t mask = (1u << TF_SHIFT)-1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
275
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
276 for (i=0; i < out_end; i+=4) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
277 uint32_t m[4] = {R[0] & mask,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
278 R[1] & mask,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
279 R[2] & mask,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
280 R[3] & mask};
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
281 uint8_t c[4] = {D.R[m[0]],
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
282 D.R[m[1]],
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
283 D.R[m[2]],
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
284 D.R[m[3]]};
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
285 out_buf[i+0] = c[0];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
286 out_buf[i+1] = c[1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
287 out_buf[i+2] = c[2];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
288 out_buf[i+3] = c[3];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
289
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
290 // RansDecAdvanceSymbolStep(&R[0], &syms[c[0]], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
291 // RansDecAdvanceSymbolStep(&R[1], &syms[c[1]], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
292 // RansDecAdvanceSymbolStep(&R[2], &syms[c[2]], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
293 // RansDecAdvanceSymbolStep(&R[3], &syms[c[3]], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
294 R[0] = syms[c[0]].freq * (R[0]>>TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
295 R[1] = syms[c[1]].freq * (R[1]>>TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
296 R[2] = syms[c[2]].freq * (R[2]>>TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
297 R[3] = syms[c[3]].freq * (R[3]>>TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
298
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
299 R[0] += m[0] - syms[c[0]].start;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
300 R[1] += m[1] - syms[c[1]].start;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
301 R[2] += m[2] - syms[c[2]].start;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
302 R[3] += m[3] - syms[c[3]].start;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
303
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
304 RansDecRenorm(&R[0], &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
305 RansDecRenorm(&R[1], &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
306 RansDecRenorm(&R[2], &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
307 RansDecRenorm(&R[3], &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
308 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
309
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
310 rans0 = R[0];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
311 rans1 = R[1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
312 rans2 = R[2];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
313 rans3 = R[3];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
314
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
315 switch(out_sz&3) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
316 unsigned char c;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
317 case 0:
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
318 break;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
319 case 1:
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
320 c = D.R[RansDecGet(&rans0, TF_SHIFT)];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
321 RansDecAdvanceSymbol(&rans0, &ptr, &syms[c], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
322 out_buf[out_end] = c;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
323 break;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
324
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
325 case 2:
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
326 c = D.R[RansDecGet(&rans0, TF_SHIFT)];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
327 RansDecAdvanceSymbol(&rans0, &ptr, &syms[c], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
328 out_buf[out_end] = c;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
329
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
330 c = D.R[RansDecGet(&rans1, TF_SHIFT)];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
331 RansDecAdvanceSymbol(&rans1, &ptr, &syms[c], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
332 out_buf[out_end+1] = c;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
333 break;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
334
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
335 case 3:
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
336 c = D.R[RansDecGet(&rans0, TF_SHIFT)];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
337 RansDecAdvanceSymbol(&rans0, &ptr, &syms[c], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
338 out_buf[out_end] = c;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
339
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
340 c = D.R[RansDecGet(&rans1, TF_SHIFT)];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
341 RansDecAdvanceSymbol(&rans1, &ptr, &syms[c], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
342 out_buf[out_end+1] = c;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
343
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
344 c = D.R[RansDecGet(&rans2, TF_SHIFT)];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
345 RansDecAdvanceSymbol(&rans2, &ptr, &syms[c], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
346 out_buf[out_end+2] = c;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
347 break;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
348 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
349
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
350 *out_size = out_sz;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
351
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
352 if (D.R) free(D.R);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
353
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
354 return (unsigned char *)out_buf;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
355 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
356
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
357 unsigned char *rans_compress_O1(unsigned char *in, unsigned int in_size,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
358 unsigned int *out_size) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
359 unsigned char *out_buf, *out_end, *cp;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
360 unsigned int last_i, tab_size, rle_i, rle_j;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
361 RansEncSymbol syms[256][256];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
362
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
363 if (in_size < 4)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
364 return rans_compress_O0(in, in_size, out_size);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
365
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
366 out_buf = malloc(1.05*in_size + 257*257*3 + 9);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
367 if (!out_buf)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
368 return NULL;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
369
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
370 out_end = out_buf + (int)(1.05*in_size) + 257*257*3 + 9;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
371 cp = out_buf+9;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
372
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
373 int F[256][256], T[256], i, j;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
374 unsigned char c;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
375
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
376 memset(F, 0, 256*256*sizeof(int));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
377 memset(T, 0, 256*sizeof(int));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
378 //for (last = 0, i=in_size-1; i>=0; i--) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
379 // F[last][c = in[i]]++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
380 // T[last]++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
381 // last = c;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
382 //}
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
383
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
384 for (last_i=i=0; i<in_size; i++) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
385 F[last_i][c = in[i]]++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
386 T[last_i]++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
387 last_i = c;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
388 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
389 F[0][in[1*(in_size>>2)]]++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
390 F[0][in[2*(in_size>>2)]]++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
391 F[0][in[3*(in_size>>2)]]++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
392 T[0]+=3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
393
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
394 // Normalise so T[i] == TOTFREQ
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
395 for (rle_i = i = 0; i < 256; i++) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
396 int t2, m, M;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
397 unsigned int x;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
398
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
399 if (T[i] == 0)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
400 continue;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
401
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
402 //uint64_t p = (TOTFREQ * TOTFREQ) / t;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
403 double p = ((double)TOTFREQ)/T[i];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
404 for (t2 = m = M = j = 0; j < 256; j++) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
405 if (!F[i][j])
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
406 continue;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
407
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
408 if (m < F[i][j])
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
409 m = F[i][j], M = j;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
410
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
411 //if ((F[i][j] = (F[i][j] * p) / TOTFREQ) == 0)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
412 if ((F[i][j] *= p) == 0)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
413 F[i][j] = 1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
414 t2 += F[i][j];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
415 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
416
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
417 t2++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
418 if (t2 < TOTFREQ)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
419 F[i][M] += TOTFREQ-t2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
420 else
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
421 F[i][M] -= t2-TOTFREQ;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
422
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
423 // Store frequency table
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
424 // i
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
425 if (rle_i) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
426 rle_i--;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
427 } else {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
428 *cp++ = i;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
429 // FIXME: could use order-0 statistics to observe which alphabet
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
430 // symbols are present and base RLE on that ordering instead.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
431 if (i && T[i-1]) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
432 for(rle_i=i+1; rle_i<256 && T[rle_i]; rle_i++)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
433 ;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
434 rle_i -= i+1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
435 *cp++ = rle_i;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
436 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
437 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
438
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
439 int *F_i_ = F[i];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
440 x = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
441 rle_j = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
442 for (j = 0; j < 256; j++) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
443 if (F_i_[j]) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
444 //fprintf(stderr, "F[%d][%d]=%d, x=%d\n", i, j, F_i_[j], x);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
445
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
446 // j
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
447 if (rle_j) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
448 rle_j--;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
449 } else {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
450 *cp++ = j;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
451 if (!rle_j && j && F_i_[j-1]) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
452 for(rle_j=j+1; rle_j<256 && F_i_[rle_j]; rle_j++)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
453 ;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
454 rle_j -= j+1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
455 *cp++ = rle_j;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
456 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
457 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
458
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
459 // F_i_[j]
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
460 if (F_i_[j]<128) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
461 *cp++ = F_i_[j];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
462 } else {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
463 *cp++ = 128 | (F_i_[j]>>8);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
464 *cp++ = F_i_[j]&0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
465 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
466
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
467 RansEncSymbolInit(&syms[i][j], x, F_i_[j], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
468 x += F_i_[j];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
469 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
470 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
471 *cp++ = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
472 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
473 *cp++ = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
474
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
475 //write(1, out_buf+4, cp-(out_buf+4));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
476 tab_size = cp - out_buf;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
477 assert(tab_size < 257*257*3);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
478
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
479 RansState rans0, rans1, rans2, rans3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
480 RansEncInit(&rans0);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
481 RansEncInit(&rans1);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
482 RansEncInit(&rans2);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
483 RansEncInit(&rans3);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
484
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
485 uint8_t* ptr = out_end;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
486
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
487 int isz4 = in_size>>2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
488 int i0 = 1*isz4-2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
489 int i1 = 2*isz4-2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
490 int i2 = 3*isz4-2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
491 int i3 = 4*isz4-2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
492
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
493 unsigned char l0 = in[i0+1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
494 unsigned char l1 = in[i1+1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
495 unsigned char l2 = in[i2+1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
496 unsigned char l3 = in[i3+1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
497
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
498 // Deal with the remainder
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
499 l3 = in[in_size-1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
500 for (i3 = in_size-2; i3 > 4*isz4-2; i3--) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
501 unsigned char c3 = in[i3];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
502 RansEncPutSymbol(&rans3, &ptr, &syms[c3][l3]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
503 l3 = c3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
504 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
505
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
506 for (; i0 >= 0; i0--, i1--, i2--, i3--) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
507 unsigned char c0, c1, c2, c3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
508 RansEncSymbol *s3 = &syms[c3 = in[i3]][l3];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
509 RansEncSymbol *s2 = &syms[c2 = in[i2]][l2];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
510 RansEncSymbol *s1 = &syms[c1 = in[i1]][l1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
511 RansEncSymbol *s0 = &syms[c0 = in[i0]][l0];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
512
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
513 RansEncPutSymbol(&rans3, &ptr, s3);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
514 RansEncPutSymbol(&rans2, &ptr, s2);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
515 RansEncPutSymbol(&rans1, &ptr, s1);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
516 RansEncPutSymbol(&rans0, &ptr, s0);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
517
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
518 l0 = c0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
519 l1 = c1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
520 l2 = c2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
521 l3 = c3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
522 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
523
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
524 RansEncPutSymbol(&rans3, &ptr, &syms[0][l3]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
525 RansEncPutSymbol(&rans2, &ptr, &syms[0][l2]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
526 RansEncPutSymbol(&rans1, &ptr, &syms[0][l1]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
527 RansEncPutSymbol(&rans0, &ptr, &syms[0][l0]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
528
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
529 RansEncFlush(&rans3, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
530 RansEncFlush(&rans2, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
531 RansEncFlush(&rans1, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
532 RansEncFlush(&rans0, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
533
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
534 *out_size = (out_end - ptr) + tab_size;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
535
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
536 cp = out_buf;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
537 *cp++ = 1; // order
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
538
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
539 *cp++ = ((*out_size-9)>> 0) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
540 *cp++ = ((*out_size-9)>> 8) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
541 *cp++ = ((*out_size-9)>>16) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
542 *cp++ = ((*out_size-9)>>24) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
543
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
544 *cp++ = (in_size>> 0) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
545 *cp++ = (in_size>> 8) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
546 *cp++ = (in_size>>16) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
547 *cp++ = (in_size>>24) & 0xff;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
548
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
549 memmove(out_buf + tab_size, ptr, out_end-ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
550
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
551 return out_buf;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
552 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
553
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
554 unsigned char *rans_uncompress_O1(unsigned char *in, unsigned int in_size,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
555 unsigned int *out_size) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
556 /* Load in the static tables */
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
557 unsigned char *cp = in + 9;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
558 int i, j = -999, x, out_sz, in_sz, rle_i, rle_j;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
559 char *out_buf;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
560 ari_decoder D[256];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
561 RansDecSymbol syms[256][256];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
562
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
563 memset(D, 0, 256*sizeof(*D));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
564
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
565 if (*in++ != 1) // Order-1 check
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
566 return NULL;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
567
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
568 in_sz = ((in[0])<<0) | ((in[1])<<8) | ((in[2])<<16) | ((in[3])<<24);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
569 out_sz = ((in[4])<<0) | ((in[5])<<8) | ((in[6])<<16) | ((in[7])<<24);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
570 if (in_sz != in_size-9)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
571 return NULL;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
572
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
573 out_buf = malloc(out_sz);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
574 if (!out_buf)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
575 return NULL;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
576
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
577 //fprintf(stderr, "out_sz=%d\n", out_sz);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
578
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
579 //i = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
580 rle_i = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
581 i = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
582 do {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
583 rle_j = x = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
584 j = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
585 do {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
586 if ((D[i].fc[j].F = *cp++) >= 128) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
587 D[i].fc[j].F &= ~128;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
588 D[i].fc[j].F = ((D[i].fc[j].F & 127) << 8) | *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
589 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
590 D[i].fc[j].C = x;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
591
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
592 //fprintf(stderr, "i=%d j=%d F=%d C=%d\n", i, j, D[i].fc[j].F, D[i].fc[j].C);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
593
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
594 if (!D[i].fc[j].F)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
595 D[i].fc[j].F = TOTFREQ;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
596
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
597 RansDecSymbolInit(&syms[i][j], D[i].fc[j].C, D[i].fc[j].F);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
598
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
599 /* Build reverse lookup table */
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
600 if (!D[i].R) D[i].R = (unsigned char *)malloc(TOTFREQ);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
601 memset(&D[i].R[x], j, D[i].fc[j].F);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
602
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
603 x += D[i].fc[j].F;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
604 assert(x <= TOTFREQ);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
605
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
606 if (!rle_j && j+1 == *cp) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
607 j = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
608 rle_j = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
609 } else if (rle_j) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
610 rle_j--;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
611 j++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
612 } else {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
613 j = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
614 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
615 } while(j);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
616
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
617 if (!rle_i && i+1 == *cp) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
618 i = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
619 rle_i = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
620 } else if (rle_i) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
621 rle_i--;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
622 i++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
623 } else {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
624 i = *cp++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
625 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
626 } while (i);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
627
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
628 // Precompute reverse lookup of frequency.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
629
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
630 RansState rans0, rans1, rans2, rans3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
631 uint8_t *ptr = cp;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
632 RansDecInit(&rans0, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
633 RansDecInit(&rans1, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
634 RansDecInit(&rans2, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
635 RansDecInit(&rans3, &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
636
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
637 int isz4 = out_sz>>2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
638 int l0 = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
639 int l1 = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
640 int l2 = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
641 int l3 = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
642 int i4[] = {0*isz4, 1*isz4, 2*isz4, 3*isz4};
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
643
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
644 RansState R[4];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
645 R[0] = rans0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
646 R[1] = rans1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
647 R[2] = rans2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
648 R[3] = rans3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
649
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
650 for (; i4[0] < isz4; i4[0]++, i4[1]++, i4[2]++, i4[3]++) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
651 uint32_t m[4] = {R[0] & ((1u << TF_SHIFT)-1),
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
652 R[1] & ((1u << TF_SHIFT)-1),
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
653 R[2] & ((1u << TF_SHIFT)-1),
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
654 R[3] & ((1u << TF_SHIFT)-1)};
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
655
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
656 uint8_t c[4] = {D[l0].R[m[0]],
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
657 D[l1].R[m[1]],
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
658 D[l2].R[m[2]],
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
659 D[l3].R[m[3]]};
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
660
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
661 out_buf[i4[0]] = c[0];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
662 out_buf[i4[1]] = c[1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
663 out_buf[i4[2]] = c[2];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
664 out_buf[i4[3]] = c[3];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
665
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
666 //RansDecAdvanceSymbolStep(&R[0], &syms[l0][c[0]], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
667 //RansDecAdvanceSymbolStep(&R[1], &syms[l1][c[1]], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
668 //RansDecAdvanceSymbolStep(&R[2], &syms[l2][c[2]], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
669 //RansDecAdvanceSymbolStep(&R[3], &syms[l3][c[3]], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
670
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
671 R[0] = syms[l0][c[0]].freq * (R[0]>>TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
672 R[1] = syms[l1][c[1]].freq * (R[1]>>TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
673 R[2] = syms[l2][c[2]].freq * (R[2]>>TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
674 R[3] = syms[l3][c[3]].freq * (R[3]>>TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
675
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
676 R[0] += m[0] - syms[l0][c[0]].start;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
677 R[1] += m[1] - syms[l1][c[1]].start;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
678 R[2] += m[2] - syms[l2][c[2]].start;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
679 R[3] += m[3] - syms[l3][c[3]].start;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
680
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
681 RansDecRenorm(&R[0], &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
682 RansDecRenorm(&R[1], &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
683 RansDecRenorm(&R[2], &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
684 RansDecRenorm(&R[3], &ptr);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
685
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
686 l0 = c[0];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
687 l1 = c[1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
688 l2 = c[2];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
689 l3 = c[3];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
690 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
691
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
692 rans0 = R[0];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
693 rans1 = R[1];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
694 rans2 = R[2];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
695 rans3 = R[3];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
696
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
697 // Remainder
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
698 for (; i4[3] < out_sz; i4[3]++) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
699 unsigned char c3 = D[l3].R[RansDecGet(&rans3, TF_SHIFT)];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
700 out_buf[i4[3]] = c3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
701 RansDecAdvanceSymbol(&rans3, &ptr, &syms[l3][c3], TF_SHIFT);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
702 l3 = c3;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
703 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
704
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
705 *out_size = out_sz;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
706
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
707 for (i = 0; i < 256; i++)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
708 if (D[i].R) free(D[i].R);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
709
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
710 return (unsigned char *)out_buf;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
711 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
712
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
713 /*-----------------------------------------------------------------------------
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
714 * Simple interface to the order-0 vs order-1 encoders and decoders.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
715 */
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
716 unsigned char *rans_compress(unsigned char *in, unsigned int in_size,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
717 unsigned int *out_size, int order) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
718 return order
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
719 ? rans_compress_O1(in, in_size, out_size)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
720 : rans_compress_O0(in, in_size, out_size);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
721 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
722
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
723 unsigned char *rans_uncompress(unsigned char *in, unsigned int in_size,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
724 unsigned int *out_size) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
725 return in[0]
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
726 ? rans_uncompress_O1(in, in_size, out_size)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
727 : rans_uncompress_O0(in, in_size, out_size);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
728 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
729
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
730
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
731 #ifdef TEST_MAIN
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
732 /*-----------------------------------------------------------------------------
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
733 * Main.
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
734 *
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
735 * This is a simple command line tool for testing order-0 and order-1
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
736 * compression using the rANS codec. Simply compile with
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
737 *
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
738 * gcc -DTEST_MAIN -O3 -I. cram/rANS_static.c -o cram/rANS_static
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
739 *
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
740 * Usage: cram/rANS_static -o0 < file > file.o0
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
741 * cram/rANS_static -d < file.o0 > file2
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
742 *
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
743 * cram/rANS_static -o1 < file > file.o1
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
744 * cram/rANS_static -d < file.o1 > file2
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
745 */
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
746 int main(int argc, char **argv) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
747 int opt, order = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
748 unsigned char in_buf[BLK_SIZE2+257*257*3];
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
749 int decode = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
750 FILE *infp = stdin, *outfp = stdout;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
751 struct timeval tv1, tv2;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
752 size_t bytes = 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
753
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
754 extern char *optarg;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
755 extern int optind;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
756
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
757 while ((opt = getopt(argc, argv, "o:d")) != -1) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
758 switch (opt) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
759 case 'o':
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
760 order = atoi(optarg);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
761 break;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
762
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
763 case 'd':
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
764 decode = 1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
765 break;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
766 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
767 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
768
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
769 order = order ? 1 : 0; // Only support O(0) and O(1)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
770
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
771 if (optind < argc) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
772 if (!(infp = fopen(argv[optind], "rb"))) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
773 perror(argv[optind]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
774 return 1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
775 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
776 optind++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
777 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
778
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
779 if (optind < argc) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
780 if (!(outfp = fopen(argv[optind], "wb"))) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
781 perror(argv[optind]);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
782 return 1;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
783 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
784 optind++;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
785 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
786
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
787 gettimeofday(&tv1, NULL);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
788
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
789 if (decode) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
790 // Only used in some test implementations of RC_GetFreq()
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
791 //RC_init();
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
792 //RC_init2();
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
793
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
794 for (;;) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
795 uint32_t in_size, out_size;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
796 unsigned char *out;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
797
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
798 if (4 != fread(&in_size, 1, 4, infp))
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
799 break;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
800 if (in_size != fread(in_buf, 1, in_size, infp)) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
801 fprintf(stderr, "Truncated input\n");
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
802 exit(1);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
803 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
804 out = rans_uncompress(in_buf, in_size, &out_size);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
805 if (!out)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
806 abort();
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
807
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
808 fwrite(out, 1, out_size, outfp);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
809 free(out);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
810
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
811 bytes += out_size;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
812 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
813 } else {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
814 for (;;) {
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
815 uint32_t in_size, out_size;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
816 unsigned char *out;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
817
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
818 in_size = fread(in_buf, 1, BLK_SIZE, infp);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
819 if (in_size <= 0)
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
820 break;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
821
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
822 out = rans_compress(in_buf, in_size, &out_size, order);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
823
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
824 fwrite(&out_size, 1, 4, outfp);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
825 fwrite(out, 1, out_size, outfp);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
826 free(out);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
827
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
828 bytes += in_size;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
829 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
830 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
831
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
832 gettimeofday(&tv2, NULL);
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
833
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
834 fprintf(stderr, "Took %ld microseconds, %5.1f MB/s\n",
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
835 (long)(tv2.tv_sec - tv1.tv_sec)*1000000 +
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
836 tv2.tv_usec - tv1.tv_usec,
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
837 (double)bytes / ((long)(tv2.tv_sec - tv1.tv_sec)*1000000 +
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
838 tv2.tv_usec - tv1.tv_usec));
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
839 return 0;
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
840 }
dfa3745e5fd8 Uploaded
youngkim
parents:
diff changeset
841 #endif