source: trunk/indexers/mg/src/images/codeoffsets.c@ 3745

Last change on this file since 3745 was 3745, checked in by mdewsnip, 21 years ago

Addition of MG package for search and retrieval

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 6.6 KB
Line 
1/**************************************************************************
2 *
3 * codeoffsets.c -- Functions which code the mark offsets
4 * Copyright (C) 1994 Stuart Inglis
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id: codeoffsets.c 3745 2003-02-20 21:20:24Z mdewsnip $
21 *
22 **************************************************************************/
23
24#include "sysfuncs.h"
25
26#include "marklist.h"
27#include "arithcode.h"
28#include "utils.h"
29
30#define TOP_INC 2
31#define MID_INC 1
32#define BOT_INC 1
33
34
35void
36EncodeOffsets (marklistptr symbol_list, int nsyms)
37{
38 int xpos = 1, xneg = 1, ypos = 1, yneg = 1;
39 marklistptr step;
40 int found;
41 int dox = 0, leveltop = 1, levelmid = 1, levelbot = 1;
42 elemlist xlist, ylist; /* all previous offsets */
43 int p, f, t, xoff, yoff, symnum, count;
44 elemlist *xcond, *ycond; /* previous offsets conditioned on symbol num */
45
46 xcond = (elemlist *) malloc (nsyms * sizeof (elemlist));
47 if (!xcond)
48 error_msg ("EncodeOffsets", "Out of memory...", "");
49 ycond = (elemlist *) malloc (nsyms * sizeof (elemlist));
50 if (!ycond)
51 error_msg ("EncodeOffsets", "Out of memory...", "");
52
53 for (t = 0; t < nsyms; t++)
54 {
55 xcond[t].head = ycond[t].head = NULL;
56 xcond[t].tot = ycond[t].tot = 0;
57 }
58 xlist.head = NULL;
59 xlist.tot = 0;
60 ylist.head = NULL;
61 ylist.tot = 0;
62 for (step = symbol_list, count = 0; step; step = step->next, count++)
63 {
64 xoff = step->data.xoffset;
65 yoff = step->data.yoffset;
66 symnum = step->data.symnum;
67 for (dox = 1; dox >= 0; dox--)
68 {
69 /* encode the offsets, x first then y */
70
71 if (dox)
72 found = elem_find (&xcond[symnum], xoff, &p, &f, &t);
73 else
74 found = elem_find (&ycond[symnum], yoff, &p, &f, &t);
75
76 if (found)
77 {
78 arithmetic_encode (0, leveltop, leveltop + levelmid + levelbot);
79 leveltop += TOP_INC;
80 arithmetic_encode (p, f, t);
81 }
82 else
83 {
84 if (dox)
85 found = elem_find (&xlist, xoff, &p, &f, &t);
86 else
87 found = elem_find (&ylist, yoff, &p, &f, &t);
88
89 if (found)
90 {
91 arithmetic_encode (leveltop, leveltop + levelmid, leveltop + levelmid + levelbot);
92 levelmid += MID_INC;
93 arithmetic_encode (p, f, t);
94 }
95 else
96 {
97 arithmetic_encode (leveltop + levelmid, leveltop + levelmid + levelbot, leveltop + levelmid + levelbot);
98 levelbot += BOT_INC;
99 if (dox)
100 EncodeGammaSigned (xoff, &xpos, &xneg);
101 else
102 EncodeGammaSigned (yoff, &ypos, &yneg);
103 }
104 }
105 if (dox)
106 {
107 elem_add (&xlist, xoff);
108 elem_add (&xcond[symnum], xoff);
109 }
110 else
111 {
112 elem_add (&ylist, yoff);
113 elem_add (&ycond[symnum], yoff);
114 }
115
116 if (leveltop + levelmid >= maxfrequency)
117 {
118 leveltop = (leveltop + 1) / 2;
119 levelmid = (levelmid + 1) / 2;
120 levelbot = (levelbot + 1) / 2;
121 }
122 }
123 }
124 for (t = 0; t < nsyms; t++)
125 {
126 elem_free (&xcond[t]);
127 elem_free (&ycond[t]);
128 }
129 elem_free (&xlist);
130 elem_free (&ylist);
131 if (V)
132 fprintf (stderr, "offset models: top %d, mid %d, bot %d\n", (leveltop - 1) / TOP_INC, (levelmid - 1) / MID_INC, (levelbot - 1) / BOT_INC);
133}
134
135
136
137
138
139void
140DecodeOffsets (marklistptr symbol_list, int nsyms)
141{
142 int xpos = 1, xneg = 1, ypos = 1, yneg = 1;
143 marklistptr step;
144 int i, target, dox;
145 int leveltop = 1, levelmid = 1, levelbot = 1;
146 elemlist xlist, ylist;
147 int p, f, t, xoff = 0, yoff = 0, symnum, count = 0;
148 elemlist *xcond, *ycond;
149
150 xcond = (elemlist *) malloc (nsyms * sizeof (elemlist));
151 if (!xcond)
152 error_msg ("EncodeOffsets", "Out of memory...", "");
153 ycond = (elemlist *) malloc (nsyms * sizeof (elemlist));
154 if (!ycond)
155 error_msg ("EncodeOffsets", "Out of memory...", "");
156
157 for (i = 0; i < nsyms; i++)
158 {
159 xcond[i].head = ycond[i].head = NULL;
160 xcond[i].tot = ycond[i].tot = 0;
161 }
162
163 xlist.head = NULL;
164 xlist.tot = 0;
165 ylist.head = NULL;
166 ylist.tot = 0;
167
168 for (step = symbol_list, count = 0; step; step = step->next, count++)
169 {
170 symnum = step->data.symnum;
171 for (dox = 1; dox >= 0; dox--)
172 {
173 /* decode x offset first, then y */
174 target = arithmetic_decode_target (leveltop + levelmid + levelbot);
175 if (target < leveltop)
176 {
177 arithmetic_decode (0, leveltop, leveltop + levelmid + levelbot);
178 leveltop += TOP_INC;
179
180 if (dox)
181 i = arithmetic_decode_target (xcond[symnum].tot);
182 else
183 i = arithmetic_decode_target (ycond[symnum].tot);
184
185 if (dox)
186 {
187 elem_getrange (&xcond[symnum], i, &xoff);
188 elem_find (&xcond[symnum], xoff, &p, &f, &t);
189 }
190 else
191 {
192 elem_getrange (&ycond[symnum], i, &yoff);
193 elem_find (&ycond[symnum], yoff, &p, &f, &t);
194 }
195 arithmetic_decode (p, f, t);
196 }
197 else if (target < leveltop + levelmid)
198 {
199 arithmetic_decode (leveltop, leveltop + levelmid, leveltop + levelmid + levelbot);
200 levelmid += MID_INC;
201
202 if (dox)
203 i = arithmetic_decode_target (xlist.tot);
204 else
205 i = arithmetic_decode_target (ylist.tot);
206
207 if (dox)
208 {
209 elem_getrange (&xlist, i, &xoff);
210 elem_find (&xlist, xoff, &p, &f, &t);
211 }
212 else
213 {
214 elem_getrange (&ylist, i, &yoff);
215 elem_find (&ylist, yoff, &p, &f, &t);
216 }
217 arithmetic_decode (p, f, t);
218 }
219 else
220 {
221 arithmetic_decode (leveltop + levelmid, leveltop + levelmid + levelbot, leveltop + levelmid + levelbot);
222 levelbot += BOT_INC;
223 if (dox)
224 xoff = DecodeGammaSigned (&xpos, &xneg);
225 else
226 yoff = DecodeGammaSigned (&ypos, &yneg);
227 }
228
229 if (dox)
230 {
231 step->data.xoffset = xoff;
232 elem_add (&xlist, xoff);
233 elem_add (&xcond[symnum], xoff);
234 }
235 else
236 {
237 step->data.yoffset = yoff;
238 elem_add (&ylist, yoff);
239 elem_add (&ycond[symnum], yoff);
240 }
241
242 if (leveltop + levelmid >= maxfrequency)
243 {
244 leveltop = (leveltop + 1) / 2;
245 levelmid = (levelmid + 1) / 2;
246 levelbot = (levelbot + 1) / 2;
247 }
248 }
249 }
250 for (t = 0; t < nsyms; t++)
251 {
252 elem_free (&xcond[t]);
253 elem_free (&ycond[t]);
254 }
255 elem_free (&xlist);
256 elem_free (&ylist);
257}
Note: See TracBrowser for help on using the repository browser.