Merge pull request #1140 from bukatlib/fix_relpath
[openjpeg.git] / src / lib / openmj2 / mqc.c
1 /*
2  * The copyright in this software is being made available under the 2-clauses
3  * BSD License, included below. This software may be subject to other third
4  * party and contributor rights, including patent rights, and no such rights
5  * are granted under this license.
6  *
7  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8  * Copyright (c) 2002-2014, Professor Benoit Macq
9  * Copyright (c) 2001-2003, David Janssens
10  * Copyright (c) 2002-2003, Yannick Verschueren
11  * Copyright (c) 2003-2007, Francois-Olivier Devaux
12  * Copyright (c) 2003-2014, Antonin Descampe
13  * Copyright (c) 2005, Herve Drolon, FreeImage Team
14  * All rights reserved.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37
38 #include "opj_includes.h"
39
40 /** @defgroup MQC MQC - Implementation of an MQ-Coder */
41 /*@{*/
42
43 /** @name Local static functions */
44 /*@{*/
45
46 /**
47 Output a byte, doing bit-stuffing if necessary.
48 After a 0xff byte, the next byte must be smaller than 0x90.
49 @param mqc MQC handle
50 */
51 static void mqc_byteout(opj_mqc_t *mqc);
52 /**
53 Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000
54 @param mqc MQC handle
55 */
56 static void mqc_renorme(opj_mqc_t *mqc);
57 /**
58 Encode the most probable symbol
59 @param mqc MQC handle
60 */
61 static void mqc_codemps(opj_mqc_t *mqc);
62 /**
63 Encode the most least symbol
64 @param mqc MQC handle
65 */
66 static void mqc_codelps(opj_mqc_t *mqc);
67 /**
68 Fill mqc->c with 1's for flushing
69 @param mqc MQC handle
70 */
71 static void mqc_setbits(opj_mqc_t *mqc);
72 /**
73 FIXME: documentation ???
74 @param mqc MQC handle
75 @return
76 */
77 static INLINE int mqc_mpsexchange(opj_mqc_t *const mqc);
78 /**
79 FIXME: documentation ???
80 @param mqc MQC handle
81 @return
82 */
83 static INLINE int mqc_lpsexchange(opj_mqc_t *const mqc);
84 /**
85 Input a byte
86 @param mqc MQC handle
87 */
88 static INLINE void mqc_bytein(opj_mqc_t *const mqc);
89 /**
90 Renormalize mqc->a and mqc->c while decoding
91 @param mqc MQC handle
92 */
93 static INLINE void mqc_renormd(opj_mqc_t *const mqc);
94 /*@}*/
95
96 /*@}*/
97
98 /* <summary> */
99 /* This array defines all the possible states for a context. */
100 /* </summary> */
101 static opj_mqc_state_t mqc_states[47 * 2] = {
102     {0x5601, 0, &mqc_states[2], &mqc_states[3]},
103     {0x5601, 1, &mqc_states[3], &mqc_states[2]},
104     {0x3401, 0, &mqc_states[4], &mqc_states[12]},
105     {0x3401, 1, &mqc_states[5], &mqc_states[13]},
106     {0x1801, 0, &mqc_states[6], &mqc_states[18]},
107     {0x1801, 1, &mqc_states[7], &mqc_states[19]},
108     {0x0ac1, 0, &mqc_states[8], &mqc_states[24]},
109     {0x0ac1, 1, &mqc_states[9], &mqc_states[25]},
110     {0x0521, 0, &mqc_states[10], &mqc_states[58]},
111     {0x0521, 1, &mqc_states[11], &mqc_states[59]},
112     {0x0221, 0, &mqc_states[76], &mqc_states[66]},
113     {0x0221, 1, &mqc_states[77], &mqc_states[67]},
114     {0x5601, 0, &mqc_states[14], &mqc_states[13]},
115     {0x5601, 1, &mqc_states[15], &mqc_states[12]},
116     {0x5401, 0, &mqc_states[16], &mqc_states[28]},
117     {0x5401, 1, &mqc_states[17], &mqc_states[29]},
118     {0x4801, 0, &mqc_states[18], &mqc_states[28]},
119     {0x4801, 1, &mqc_states[19], &mqc_states[29]},
120     {0x3801, 0, &mqc_states[20], &mqc_states[28]},
121     {0x3801, 1, &mqc_states[21], &mqc_states[29]},
122     {0x3001, 0, &mqc_states[22], &mqc_states[34]},
123     {0x3001, 1, &mqc_states[23], &mqc_states[35]},
124     {0x2401, 0, &mqc_states[24], &mqc_states[36]},
125     {0x2401, 1, &mqc_states[25], &mqc_states[37]},
126     {0x1c01, 0, &mqc_states[26], &mqc_states[40]},
127     {0x1c01, 1, &mqc_states[27], &mqc_states[41]},
128     {0x1601, 0, &mqc_states[58], &mqc_states[42]},
129     {0x1601, 1, &mqc_states[59], &mqc_states[43]},
130     {0x5601, 0, &mqc_states[30], &mqc_states[29]},
131     {0x5601, 1, &mqc_states[31], &mqc_states[28]},
132     {0x5401, 0, &mqc_states[32], &mqc_states[28]},
133     {0x5401, 1, &mqc_states[33], &mqc_states[29]},
134     {0x5101, 0, &mqc_states[34], &mqc_states[30]},
135     {0x5101, 1, &mqc_states[35], &mqc_states[31]},
136     {0x4801, 0, &mqc_states[36], &mqc_states[32]},
137     {0x4801, 1, &mqc_states[37], &mqc_states[33]},
138     {0x3801, 0, &mqc_states[38], &mqc_states[34]},
139     {0x3801, 1, &mqc_states[39], &mqc_states[35]},
140     {0x3401, 0, &mqc_states[40], &mqc_states[36]},
141     {0x3401, 1, &mqc_states[41], &mqc_states[37]},
142     {0x3001, 0, &mqc_states[42], &mqc_states[38]},
143     {0x3001, 1, &mqc_states[43], &mqc_states[39]},
144     {0x2801, 0, &mqc_states[44], &mqc_states[38]},
145     {0x2801, 1, &mqc_states[45], &mqc_states[39]},
146     {0x2401, 0, &mqc_states[46], &mqc_states[40]},
147     {0x2401, 1, &mqc_states[47], &mqc_states[41]},
148     {0x2201, 0, &mqc_states[48], &mqc_states[42]},
149     {0x2201, 1, &mqc_states[49], &mqc_states[43]},
150     {0x1c01, 0, &mqc_states[50], &mqc_states[44]},
151     {0x1c01, 1, &mqc_states[51], &mqc_states[45]},
152     {0x1801, 0, &mqc_states[52], &mqc_states[46]},
153     {0x1801, 1, &mqc_states[53], &mqc_states[47]},
154     {0x1601, 0, &mqc_states[54], &mqc_states[48]},
155     {0x1601, 1, &mqc_states[55], &mqc_states[49]},
156     {0x1401, 0, &mqc_states[56], &mqc_states[50]},
157     {0x1401, 1, &mqc_states[57], &mqc_states[51]},
158     {0x1201, 0, &mqc_states[58], &mqc_states[52]},
159     {0x1201, 1, &mqc_states[59], &mqc_states[53]},
160     {0x1101, 0, &mqc_states[60], &mqc_states[54]},
161     {0x1101, 1, &mqc_states[61], &mqc_states[55]},
162     {0x0ac1, 0, &mqc_states[62], &mqc_states[56]},
163     {0x0ac1, 1, &mqc_states[63], &mqc_states[57]},
164     {0x09c1, 0, &mqc_states[64], &mqc_states[58]},
165     {0x09c1, 1, &mqc_states[65], &mqc_states[59]},
166     {0x08a1, 0, &mqc_states[66], &mqc_states[60]},
167     {0x08a1, 1, &mqc_states[67], &mqc_states[61]},
168     {0x0521, 0, &mqc_states[68], &mqc_states[62]},
169     {0x0521, 1, &mqc_states[69], &mqc_states[63]},
170     {0x0441, 0, &mqc_states[70], &mqc_states[64]},
171     {0x0441, 1, &mqc_states[71], &mqc_states[65]},
172     {0x02a1, 0, &mqc_states[72], &mqc_states[66]},
173     {0x02a1, 1, &mqc_states[73], &mqc_states[67]},
174     {0x0221, 0, &mqc_states[74], &mqc_states[68]},
175     {0x0221, 1, &mqc_states[75], &mqc_states[69]},
176     {0x0141, 0, &mqc_states[76], &mqc_states[70]},
177     {0x0141, 1, &mqc_states[77], &mqc_states[71]},
178     {0x0111, 0, &mqc_states[78], &mqc_states[72]},
179     {0x0111, 1, &mqc_states[79], &mqc_states[73]},
180     {0x0085, 0, &mqc_states[80], &mqc_states[74]},
181     {0x0085, 1, &mqc_states[81], &mqc_states[75]},
182     {0x0049, 0, &mqc_states[82], &mqc_states[76]},
183     {0x0049, 1, &mqc_states[83], &mqc_states[77]},
184     {0x0025, 0, &mqc_states[84], &mqc_states[78]},
185     {0x0025, 1, &mqc_states[85], &mqc_states[79]},
186     {0x0015, 0, &mqc_states[86], &mqc_states[80]},
187     {0x0015, 1, &mqc_states[87], &mqc_states[81]},
188     {0x0009, 0, &mqc_states[88], &mqc_states[82]},
189     {0x0009, 1, &mqc_states[89], &mqc_states[83]},
190     {0x0005, 0, &mqc_states[90], &mqc_states[84]},
191     {0x0005, 1, &mqc_states[91], &mqc_states[85]},
192     {0x0001, 0, &mqc_states[90], &mqc_states[86]},
193     {0x0001, 1, &mqc_states[91], &mqc_states[87]},
194     {0x5601, 0, &mqc_states[92], &mqc_states[92]},
195     {0x5601, 1, &mqc_states[93], &mqc_states[93]},
196 };
197
198 /*
199 ==========================================================
200    local functions
201 ==========================================================
202 */
203
204 static void mqc_byteout(opj_mqc_t *mqc)
205 {
206     if (*mqc->bp == 0xff) {
207         mqc->bp++;
208         *mqc->bp = mqc->c >> 20;
209         mqc->c &= 0xfffff;
210         mqc->ct = 7;
211     } else {
212         if ((mqc->c & 0x8000000) == 0) {    /* ((mqc->c&0x8000000)==0) CHANGE */
213             mqc->bp++;
214             *mqc->bp = mqc->c >> 19;
215             mqc->c &= 0x7ffff;
216             mqc->ct = 8;
217         } else {
218             (*mqc->bp)++;
219             if (*mqc->bp == 0xff) {
220                 mqc->c &= 0x7ffffff;
221                 mqc->bp++;
222                 *mqc->bp = mqc->c >> 20;
223                 mqc->c &= 0xfffff;
224                 mqc->ct = 7;
225             } else {
226                 mqc->bp++;
227                 *mqc->bp = mqc->c >> 19;
228                 mqc->c &= 0x7ffff;
229                 mqc->ct = 8;
230             }
231         }
232     }
233 }
234
235 static void mqc_renorme(opj_mqc_t *mqc)
236 {
237     do {
238         mqc->a <<= 1;
239         mqc->c <<= 1;
240         mqc->ct--;
241         if (mqc->ct == 0) {
242             mqc_byteout(mqc);
243         }
244     } while ((mqc->a & 0x8000) == 0);
245 }
246
247 static void mqc_codemps(opj_mqc_t *mqc)
248 {
249     mqc->a -= (*mqc->curctx)->qeval;
250     if ((mqc->a & 0x8000) == 0) {
251         if (mqc->a < (*mqc->curctx)->qeval) {
252             mqc->a = (*mqc->curctx)->qeval;
253         } else {
254             mqc->c += (*mqc->curctx)->qeval;
255         }
256         *mqc->curctx = (*mqc->curctx)->nmps;
257         mqc_renorme(mqc);
258     } else {
259         mqc->c += (*mqc->curctx)->qeval;
260     }
261 }
262
263 static void mqc_codelps(opj_mqc_t *mqc)
264 {
265     mqc->a -= (*mqc->curctx)->qeval;
266     if (mqc->a < (*mqc->curctx)->qeval) {
267         mqc->c += (*mqc->curctx)->qeval;
268     } else {
269         mqc->a = (*mqc->curctx)->qeval;
270     }
271     *mqc->curctx = (*mqc->curctx)->nlps;
272     mqc_renorme(mqc);
273 }
274
275 static void mqc_setbits(opj_mqc_t *mqc)
276 {
277     unsigned int tempc = mqc->c + mqc->a;
278     mqc->c |= 0xffff;
279     if (mqc->c >= tempc) {
280         mqc->c -= 0x8000;
281     }
282 }
283
284 static INLINE int mqc_mpsexchange(opj_mqc_t *const mqc)
285 {
286     int d;
287     if (mqc->a < (*mqc->curctx)->qeval) {
288         d = 1 - (*mqc->curctx)->mps;
289         *mqc->curctx = (*mqc->curctx)->nlps;
290     } else {
291         d = (*mqc->curctx)->mps;
292         *mqc->curctx = (*mqc->curctx)->nmps;
293     }
294
295     return d;
296 }
297
298 static INLINE int mqc_lpsexchange(opj_mqc_t *const mqc)
299 {
300     int d;
301     if (mqc->a < (*mqc->curctx)->qeval) {
302         mqc->a = (*mqc->curctx)->qeval;
303         d = (*mqc->curctx)->mps;
304         *mqc->curctx = (*mqc->curctx)->nmps;
305     } else {
306         mqc->a = (*mqc->curctx)->qeval;
307         d = 1 - (*mqc->curctx)->mps;
308         *mqc->curctx = (*mqc->curctx)->nlps;
309     }
310
311     return d;
312 }
313
314 #ifdef MQC_PERF_OPT
315 static INLINE void mqc_bytein(opj_mqc_t *const mqc)
316 {
317     unsigned int i = *((unsigned int *) mqc->bp);
318     mqc->c += i & 0xffff00;
319     mqc->ct = i & 0x0f;
320     mqc->bp += (i >> 2) & 0x04;
321 }
322 #else
323 static void mqc_bytein(opj_mqc_t *const mqc)
324 {
325     if (mqc->bp != mqc->end) {
326         unsigned int c;
327         if (mqc->bp + 1 != mqc->end) {
328             c = *(mqc->bp + 1);
329         } else {
330             c = 0xff;
331         }
332         if (*mqc->bp == 0xff) {
333             if (c > 0x8f) {
334                 mqc->c += 0xff00;
335                 mqc->ct = 8;
336             } else {
337                 mqc->bp++;
338                 mqc->c += c << 9;
339                 mqc->ct = 7;
340             }
341         } else {
342             mqc->bp++;
343             mqc->c += c << 8;
344             mqc->ct = 8;
345         }
346     } else {
347         mqc->c += 0xff00;
348         mqc->ct = 8;
349     }
350 }
351 #endif
352
353 static INLINE void mqc_renormd(opj_mqc_t *const mqc)
354 {
355     do {
356         if (mqc->ct == 0) {
357             mqc_bytein(mqc);
358         }
359         mqc->a <<= 1;
360         mqc->c <<= 1;
361         mqc->ct--;
362     } while (mqc->a < 0x8000);
363 }
364
365 /*
366 ==========================================================
367    MQ-Coder interface
368 ==========================================================
369 */
370
371 opj_mqc_t* mqc_create(void)
372 {
373     opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t));
374 #ifdef MQC_PERF_OPT
375     mqc->buffer = NULL;
376 #endif
377     return mqc;
378 }
379
380 void mqc_destroy(opj_mqc_t *mqc)
381 {
382     if (mqc) {
383 #ifdef MQC_PERF_OPT
384         if (mqc->buffer) {
385             opj_free(mqc->buffer);
386         }
387 #endif
388         opj_free(mqc);
389     }
390 }
391
392 int mqc_numbytes(opj_mqc_t *mqc)
393 {
394     return mqc->bp - mqc->start;
395 }
396
397 void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp)
398 {
399     mqc_setcurctx(mqc, 0);
400     mqc->a = 0x8000;
401     mqc->c = 0;
402     mqc->bp = bp - 1;
403     mqc->ct = 12;
404     if (*mqc->bp == 0xff) {
405         mqc->ct = 13;
406     }
407     mqc->start = bp;
408 }
409
410 void mqc_encode(opj_mqc_t *mqc, int d)
411 {
412     if ((*mqc->curctx)->mps == d) {
413         mqc_codemps(mqc);
414     } else {
415         mqc_codelps(mqc);
416     }
417 }
418
419 void mqc_flush(opj_mqc_t *mqc)
420 {
421     mqc_setbits(mqc);
422     mqc->c <<= mqc->ct;
423     mqc_byteout(mqc);
424     mqc->c <<= mqc->ct;
425     mqc_byteout(mqc);
426
427     if (*mqc->bp != 0xff) {
428         mqc->bp++;
429     }
430 }
431
432 void mqc_bypass_init_enc(opj_mqc_t *mqc)
433 {
434     mqc->c = 0;
435     mqc->ct = 8;
436     /*if (*mqc->bp == 0xff) {
437     mqc->ct = 7;
438      } */
439 }
440
441 void mqc_bypass_enc(opj_mqc_t *mqc, int d)
442 {
443     mqc->ct--;
444     mqc->c = mqc->c + (d << mqc->ct);
445     if (mqc->ct == 0) {
446         mqc->bp++;
447         *mqc->bp = mqc->c;
448         mqc->ct = 8;
449         if (*mqc->bp == 0xff) {
450             mqc->ct = 7;
451         }
452         mqc->c = 0;
453     }
454 }
455
456 int mqc_bypass_flush_enc(opj_mqc_t *mqc)
457 {
458     unsigned char bit_padding;
459
460     bit_padding = 0;
461
462     if (mqc->ct != 0) {
463         while (mqc->ct > 0) {
464             mqc->ct--;
465             mqc->c += bit_padding << mqc->ct;
466             bit_padding = (bit_padding + 1) & 0x01;
467         }
468         mqc->bp++;
469         *mqc->bp = mqc->c;
470         mqc->ct = 8;
471         mqc->c = 0;
472     }
473
474     return 1;
475 }
476
477 void mqc_reset_enc(opj_mqc_t *mqc)
478 {
479     mqc_resetstates(mqc);
480     mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
481     mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
482     mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
483 }
484
485 int mqc_restart_enc(opj_mqc_t *mqc)
486 {
487     int correction = 1;
488
489     /* <flush part> */
490     int n = 27 - 15 - mqc->ct;
491     mqc->c <<= mqc->ct;
492     while (n > 0) {
493         mqc_byteout(mqc);
494         n -= mqc->ct;
495         mqc->c <<= mqc->ct;
496     }
497     mqc_byteout(mqc);
498
499     return correction;
500 }
501
502 void mqc_restart_init_enc(opj_mqc_t *mqc)
503 {
504     /* <Re-init part> */
505     mqc_setcurctx(mqc, 0);
506     mqc->a = 0x8000;
507     mqc->c = 0;
508     mqc->ct = 12;
509     mqc->bp--;
510     if (*mqc->bp == 0xff) {
511         mqc->ct = 13;
512     }
513 }
514
515 void mqc_erterm_enc(opj_mqc_t *mqc)
516 {
517     int k = 11 - mqc->ct + 1;
518
519     while (k > 0) {
520         mqc->c <<= mqc->ct;
521         mqc->ct = 0;
522         mqc_byteout(mqc);
523         k -= mqc->ct;
524     }
525
526     if (*mqc->bp != 0xff) {
527         mqc_byteout(mqc);
528     }
529 }
530
531 void mqc_segmark_enc(opj_mqc_t *mqc)
532 {
533     int i;
534     mqc_setcurctx(mqc, 18);
535
536     for (i = 1; i < 5; i++) {
537         mqc_encode(mqc, i % 2);
538     }
539 }
540
541 void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len)
542 {
543     mqc_setcurctx(mqc, 0);
544     mqc->start = bp;
545     mqc->end = bp + len;
546     mqc->bp = bp;
547     if (len == 0) {
548         mqc->c = 0xff << 16;
549     } else {
550         mqc->c = *mqc->bp << 16;
551     }
552
553 #ifdef MQC_PERF_OPT
554     {
555         unsigned int c;
556         unsigned int *ip;
557         unsigned char *end = mqc->end - 1;
558         mqc->buffer = opj_realloc(mqc->buffer, (len + 1) * sizeof(unsigned int));
559         ip = (unsigned int *) mqc->buffer;
560
561         while (bp < end) {
562             c = *(bp + 1);
563             if (*bp == 0xff) {
564                 if (c > 0x8f) {
565                     break;
566                 } else {
567                     *ip = 0x00000017 | (c << 9);
568                 }
569             } else {
570                 *ip = 0x00000018 | (c << 8);
571             }
572             bp++;
573             ip++;
574         }
575
576         /* Handle last byte of data */
577         c = 0xff;
578         if (*bp == 0xff) {
579             *ip = 0x0000ff18;
580         } else {
581             bp++;
582             *ip = 0x00000018 | (c << 8);
583         }
584         ip++;
585
586         *ip = 0x0000ff08;
587         mqc->bp = mqc->buffer;
588     }
589 #endif
590     mqc_bytein(mqc);
591     mqc->c <<= 7;
592     mqc->ct -= 7;
593     mqc->a = 0x8000;
594 }
595
596 int mqc_decode(opj_mqc_t *const mqc)
597 {
598     int d;
599     mqc->a -= (*mqc->curctx)->qeval;
600     if ((mqc->c >> 16) < (*mqc->curctx)->qeval) {
601         d = mqc_lpsexchange(mqc);
602         mqc_renormd(mqc);
603     } else {
604         mqc->c -= (*mqc->curctx)->qeval << 16;
605         if ((mqc->a & 0x8000) == 0) {
606             d = mqc_mpsexchange(mqc);
607             mqc_renormd(mqc);
608         } else {
609             d = (*mqc->curctx)->mps;
610         }
611     }
612
613     return d;
614 }
615
616 void mqc_resetstates(opj_mqc_t *mqc)
617 {
618     int i;
619     for (i = 0; i < MQC_NUMCTXS; i++) {
620         mqc->ctxs[i] = mqc_states;
621     }
622 }
623
624 void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob)
625 {
626     mqc->ctxs[ctxno] = &mqc_states[msb + (prob << 1)];
627 }
628
629