Coverage Report

Created: 2026-04-09 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/jpegxr/algo.c
Line
Count
Source
1
/*
2
**
3
** $Id: algo.c,v 1.11 2011-12-19 15:39:50 thor Exp $
4
**
5
**
6
*/
7
8
/*************************************************************************
9
*
10
* This software module was originally contributed by Microsoft
11
* Corporation in the course of development of the
12
* ITU-T T.832 | ISO/IEC 29199-2 ("JPEG XR") format standard for
13
* reference purposes and its performance may not have been optimized.
14
*
15
* This software module is an implementation of one or more
16
* tools as specified by the JPEG XR standard.
17
*
18
* ITU/ISO/IEC give You a royalty-free, worldwide, non-exclusive
19
* copyright license to copy, distribute, and make derivative works
20
* of this software module or modifications thereof for use in
21
* products claiming conformance to the JPEG XR standard as
22
* specified by ITU-T T.832 | ISO/IEC 29199-2.
23
*
24
* ITU/ISO/IEC give users the same free license to this software
25
* module or modifications thereof for research purposes and further
26
* ITU/ISO/IEC standardization.
27
*
28
* Those intending to use this software module in products are advised
29
* that its use may infringe existing patents. ITU/ISO/IEC have no
30
* liability for use of this software module or modifications thereof.
31
*
32
* Copyright is not released for products that do not conform to
33
* to the JPEG XR standard as specified by ITU-T T.832 |
34
* ISO/IEC 29199-2.
35
*
36
******** Section to be removed when the standard is published ************
37
*
38
* Assurance that the contributed software module can be used
39
* (1) in the ITU-T "T.JXR" | ISO/IEC 29199 ("JPEG XR") standard once the
40
* standard has been adopted; and
41
* (2) to develop the JPEG XR standard:
42
*
43
* Microsoft Corporation and any subsequent contributors to the development
44
* of this software grant ITU/ISO/IEC all rights necessary to include
45
* the originally developed software module or modifications thereof in the
46
* JPEG XR standard and to permit ITU/ISO/IEC to offer such a royalty-free,
47
* worldwide, non-exclusive copyright license to copy, distribute, and make
48
* derivative works of this software module or modifications thereof for
49
* use in products claiming conformance to the JPEG XR standard as
50
* specified by ITU-T T.832 | ISO/IEC 29199-2, and to the extent that
51
* such originally developed software module or portions of it are included
52
* in an ITU/ISO/IEC standard. To the extent that the original contributors
53
* may own patent rights that would be required to make, use, or sell the
54
* originally developed software module or portions thereof included in the
55
* ITU/ISO/IEC standard in a conforming product, the contributors will
56
* assure ITU/ISO/IEC that they are willing to negotiate licenses under
57
* reasonable and non-discriminatory terms and conditions with
58
* applicants throughout the world and in accordance with their patent
59
* rights declarations made to ITU/ISO/IEC (if any).
60
*
61
* Microsoft, any subsequent contributors, and ITU/ISO/IEC additionally
62
* gives You a free license to this software module or modifications
63
* thereof for the sole purpose of developing the JPEG XR standard.
64
*
65
******** end of section to be removed when the standard is published *****
66
*
67
* Microsoft Corporation retains full right to modify and use the code
68
* for its own purpose, to assign or donate the code to a third party,
69
* and to inhibit third parties from using the code for products that
70
* do not conform to the JPEG XR standard as specified by ITU-T T.832 |
71
* ISO/IEC 29199-2.
72
*
73
* This copyright notice must be included in all copies or derivative
74
* works.
75
*
76
* Copyright (c) ITU-T/ISO/IEC 2008, 2009.
77
***********************************************************************/
78
79
#ifdef _MSC_VER
80
#pragma comment (user,"$Id: algo.c,v 1.11 2011-12-19 15:39:50 thor Exp $")
81
#endif
82
83
/*
84
* This file contains many common algorithms of JPEGXR processing.
85
*/
86
87
# include "jxr_priv.h"
88
# include <stdio.h>
89
# include <stdlib.h>
90
# include <limits.h>
91
# include <assert.h>
92
93
static void InitVLCTable2(jxr_image_t image, int vlc_select);
94
95
const int _jxr_hp_scan_map[16] = { 0, 1, 4, 5,
96
2, 3, 6, 7,
97
8, 9,12,13,
98
10,11,14,15 };
99
100
static const unsigned ScanTotals[15] ={32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4};
101
static int long_word_flag = 0;
102
103
/*
104
* These two functions implemented floor(x/2) and ceil(x/2). Note that
105
* in C/C++ x/2 is NOT the same as floor(x/2) if x<0. It may be on
106
* some systems, but not in general. So we do all arithmetic with
107
* positive values and get the floor/ceil right by manipulating signs
108
* and rounding afterwards. The YUV444 --> RGB transform must get this
109
* rounding exactly right or there may be losses in the lossless transform.
110
*/
111
int _jxr_floor_div2(int x)
112
0
{
113
0
    if (x >= 0)
114
0
        return x/2;
115
0
    else
116
0
        return -((-x+1)/2);
117
0
}
118
119
int _jxr_ceil_div2(int x)
120
0
{
121
0
    if (x >= 0)
122
0
        return (x+1)/2;
123
0
    else
124
0
        return -((-x)/2);
125
0
}
126
127
int _jxr_quant_map(jxr_image_t image, int x, int shift)
128
0
{
129
0
    int man, exp;
130
131
0
    if (x == 0)
132
0
        return 1;
133
134
0
    if (image->scaled_flag) {
135
0
        if (x < 16) {
136
0
            man = x;
137
0
            exp = shift;
138
0
        } else {
139
0
            man = 16 + (x%16);
140
0
            exp = ((x>>4) - 1) + shift;
141
0
        }
142
0
    } else {
143
0
        if (x < 32) {
144
0
            man = (x + 3) >> 2;
145
0
            exp = 0;
146
0
        } else if (x < 48) {
147
0
            man = (16 + (x%16) + 1) >> 1;
148
0
            exp = (x>>4) - 2;
149
0
        } else {
150
0
            man = 16 + (x%16);
151
0
            exp = (x>>4) - 3;
152
0
        }
153
0
    }
154
155
0
    return man << exp;
156
0
}
157
158
int _jxr_vlc_select(int band, int chroma_flag)
159
0
{
160
0
    int vlc_select = 0;
161
162
    /* Based on the band and the chroma flag, select the vlc table
163
    that we want to use for the ABSLEVEL_INDEX decoder. */
164
0
    switch (band) {
165
0
        case 0: /* DC */
166
0
            if (chroma_flag)
167
0
                vlc_select = AbsLevelIndDCChr;
168
0
            else
169
0
                vlc_select = AbsLevelIndDCLum;
170
0
            break;
171
0
        case 1: /* LP */
172
0
            if (chroma_flag)
173
0
                vlc_select = AbsLevelIndLP1;
174
0
            else
175
0
                vlc_select = AbsLevelIndLP0;
176
0
            break;
177
0
        case 2: /* HP */
178
0
            if (chroma_flag)
179
0
                vlc_select = AbsLevelIndHP1;
180
0
            else
181
0
                vlc_select = AbsLevelIndHP0;
182
0
            break;
183
0
        default:
184
0
            assert(0);
185
0
            break;
186
0
    }
187
188
0
    return vlc_select;
189
0
}
190
191
void _jxr_InitVLCTable(jxr_image_t image, int vlc_select)
192
0
{
193
0
    struct adaptive_vlc_s*table = image->vlc_table + vlc_select;
194
0
    table->table = 0;
195
0
    table->deltatable = 0;
196
0
    table->discriminant = 0;
197
0
}
198
199
static void InitVLCTable2(jxr_image_t image, int vlc_select)
200
0
{
201
0
    struct adaptive_vlc_s*table = image->vlc_table + vlc_select;
202
0
    table->table = 1;
203
0
    table->deltatable = 0;
204
0
    table->delta2table = 1;
205
0
    table->discriminant = 0;
206
0
    table->discriminant2 = 0;
207
0
}
208
209
/*
210
* This function is for running the adapt for VLC machines that have
211
* only 2 tables. In this case, only the table and discriminant
212
* members are used, and the table is 0 or 1.
213
*/
214
void _jxr_AdaptVLCTable(jxr_image_t image, int vlc_select)
215
0
{
216
0
    const int cLowerBound = -8;
217
0
    const int cUpperBound = 8;
218
219
0
    struct adaptive_vlc_s*table = image->vlc_table + vlc_select;
220
0
    const int max_index = 1; /* Only 2 code tables. */
221
222
0
    table->deltatable = 0;
223
0
    if ((table->discriminant < cLowerBound) && (table->table != 0)) {
224
0
        table->table -= 1;
225
0
        table->discriminant = 0;
226
0
    } else if ((table->discriminant > cUpperBound) && (table->table != max_index)) {
227
0
        table->table += 1;
228
0
        table->discriminant = 0;
229
0
    } else {
230
0
        if (table->discriminant < -64) table->discriminant = -64;
231
0
        if (table->discriminant > 64) table->discriminant = 64;
232
0
    }
233
0
}
234
235
static void AdaptVLCTable2(jxr_image_t image, int vlc_select, int max_index)
236
0
{
237
0
    const int LOWER_BOUND = -8;
238
0
    const int UPPER_BOUND = 8;
239
240
0
    struct adaptive_vlc_s*table = image->vlc_table + vlc_select;
241
242
0
    int disc_lo = table->discriminant;
243
0
    int disc_hi = table->discriminant2;
244
245
0
    int change_flag = 0;
246
247
0
    if (disc_lo < LOWER_BOUND && table->table > 0) {
248
0
        table->table -= 1;
249
0
        change_flag = 1;
250
251
0
    } else if (disc_hi > UPPER_BOUND && table->table < max_index) {
252
0
        table->table += 1;
253
0
        change_flag = 1;
254
0
    }
255
256
257
0
    if (change_flag) {
258
0
        table->discriminant = 0;
259
0
        table->discriminant2 = 0;
260
261
0
        if (table->table == max_index) {
262
0
            table->deltatable = table->table - 1;
263
0
            table->delta2table = table->table - 1;
264
0
        } else if (table->table == 0) {
265
0
            table->deltatable = table->table;
266
0
            table->delta2table = table->table;
267
0
        } else {
268
0
            table->deltatable = table->table - 1;
269
0
            table->delta2table = table->table;
270
0
        }
271
272
0
    } else {
273
0
        if (table->discriminant < -64) table->discriminant = -64;
274
0
        if (table->discriminant > 64) table->discriminant = 64;
275
0
        if (table->discriminant2 < -64) table->discriminant2 = -64;
276
0
        if (table->discriminant2 > 64) table->discriminant2 = 64;
277
0
    }
278
0
}
279
280
void _jxr_AdaptLP(jxr_image_t image)
281
0
{
282
0
    AdaptVLCTable2(image, DecFirstIndLPLum, 4);
283
0
    AdaptVLCTable2(image, DecIndLPLum0, 3);
284
0
    AdaptVLCTable2(image, DecIndLPLum1, 3);
285
0
    AdaptVLCTable2(image, DecFirstIndLPChr, 4);
286
0
    AdaptVLCTable2(image, DecIndLPChr0, 3);
287
0
    AdaptVLCTable2(image, DecIndLPChr1, 3);
288
289
0
    _jxr_AdaptVLCTable(image, AbsLevelIndLP0);
290
0
    _jxr_AdaptVLCTable(image, AbsLevelIndLP1);
291
292
0
    DEBUG(" AdaptLP: DecFirstIndLPLum=%d\n", image->vlc_table[DecFirstIndLPLum].table);
293
0
    DEBUG(" : DecIndLPLum0=%d\n", image->vlc_table[DecIndLPLum0].table);
294
0
    DEBUG(" : DecIndLPLum1=%d\n", image->vlc_table[DecIndLPLum1].table);
295
0
    DEBUG(" : DecFirstIndLPChr=%d\n", image->vlc_table[DecFirstIndLPChr].table);
296
0
    DEBUG(" : DecIndLPChr0=%d\n", image->vlc_table[DecIndLPChr0].table);
297
0
    DEBUG(" : DecIndLPChr1=%d\n", image->vlc_table[DecIndLPChr1].table);
298
0
}
299
300
void _jxr_AdaptHP(jxr_image_t image)
301
0
{
302
0
    AdaptVLCTable2(image, DecFirstIndHPLum, 4);
303
0
    AdaptVLCTable2(image, DecIndHPLum0, 3);
304
0
    AdaptVLCTable2(image, DecIndHPLum1, 3);
305
0
    AdaptVLCTable2(image, DecFirstIndHPChr, 4);
306
0
    AdaptVLCTable2(image, DecIndHPChr0, 3);
307
0
    AdaptVLCTable2(image, DecIndHPChr1, 3);
308
309
0
    _jxr_AdaptVLCTable(image, AbsLevelIndHP0);
310
0
    _jxr_AdaptVLCTable(image, AbsLevelIndHP1);
311
312
0
    _jxr_AdaptVLCTable(image, DecNumCBP);
313
0
    _jxr_AdaptVLCTable(image, DecNumBlkCBP);
314
0
}
315
316
/*
317
* Despite the name, this function doesn't actually reset a
318
* context. It uses the tx (X position of the time) and mx (X position
319
* of the macroblock in the tile) to calculate true or false that the
320
* caller should invoke a context reset.
321
*/
322
int _jxr_InitContext(jxr_image_t image, unsigned tx, unsigned ty,
323
                     unsigned mx, unsigned my)
324
0
{
325
0
    if (mx == 0 && my == 0)
326
0
        return 1;
327
0
    else
328
0
        return 0;
329
0
}
330
331
/*
332
* This function guards Adapt?? functions that are called during the
333
* parse. At the end of a MB where this function returns true, the
334
* processing function will call the Adapt?? function.
335
*
336
* NOTE: It is *correct* that this function is true for the first and
337
* the last macroblock. This allows some far right context of a tile
338
* to inform the first column of the next line, but also allows crazy
339
* differences to be adapted away.
340
*/
341
int _jxr_ResetContext(jxr_image_t image, unsigned tx, unsigned mx)
342
0
{
343
0
    assert(tx < image->tile_columns);
344
0
    assert(image->tile_column_width);
345
    /* Return true for every 16 macroblocks in the tile. */
346
0
    if (mx%16 == 0)
347
0
        return 1;
348
    /* Return true for the final macroblock in the tile. */
349
0
    if (image->tile_column_width[tx] == mx+1)
350
0
        return 1;
351
352
0
    return 0;
353
0
}
354
355
int _jxr_ResetTotals(jxr_image_t image, unsigned mx)
356
0
{
357
0
    if (mx%16 == 0)
358
0
        return 1;
359
0
    else return 0;
360
0
}
361
362
void _jxr_InitializeModelMB(struct model_s*model, int band)
363
0
{
364
0
    assert(band <= 2);
365
366
0
    model->state[0] = 0;
367
0
    model->state[1] = 0;
368
0
    model->bits[0] = (2-band) * 4;
369
0
    model->bits[1] = (2-band) * 4;
370
0
}
371
372
void _jxr_UpdateModelMB(jxr_image_t image, int lap_mean[2], struct model_s*model, int band)
373
0
{
374
0
    const int modelweight = 70;
375
0
    static const int weight0[3] = { 240, 12, 1 };
376
0
    static const int weight1[3][MAX_CHANNELS] = {
377
0
        {0,240,120,80, 60,48,40,34, 30,27,24,22, 20,18,17,16 },
378
0
        {0,12,6,4, 3,2,2,2, 2,1,1,1, 1,1,1,1 },
379
0
        {0,16,8,5, 4,3,3,2, 2,2,2,1, 1,1,1,1 }
380
0
    };
381
0
    static const int weight2[6] = { 120,37,2, 120,18,1 };
382
0
    int j;
383
384
0
    assert(band < 3);
385
386
0
    lap_mean[0] *= weight0[band];
387
0
    switch (image->use_clr_fmt) {
388
0
        case 1: /* YUV420 */
389
0
            lap_mean[1] *= weight2[band];
390
0
            break;
391
0
        case 2: /* YUV422 */
392
0
            lap_mean[1] *= weight2[3+band];
393
0
            break;
394
0
        default:
395
0
            lap_mean[1] *= weight1[band][image->num_channels-1];
396
0
            if (band == 2 /*HP*/)
397
0
                lap_mean[1] >>= 4;
398
0
            break;
399
0
    }
400
401
0
    for (j = 0; j < 2; j += 1) {
402
0
        int ms = model->state[j];
403
0
        int delta = (lap_mean[j] - modelweight) >> 2;
404
405
0
        if (delta <= -8) {
406
0
            delta += 4;
407
0
            if (delta < -16)
408
0
                delta = -16;
409
0
            ms += delta;
410
0
            if (ms < -8) {
411
0
                if (model->bits[j] == 0) {
412
0
                    ms = -8;
413
0
                } else {
414
0
                    ms = 0;
415
0
                    model->bits[j] -= 1;
416
0
                }
417
0
            }
418
0
        } else if (delta >= 8) {
419
0
            delta -= 4;
420
0
            if (delta > 15)
421
0
                delta = 15;
422
0
            ms += delta;
423
0
            if (ms > 8) {
424
0
                if (model->bits[j] >= 15) {
425
0
                    model->bits[j] = 15;
426
0
                    ms = 8;
427
0
                } else {
428
0
                    ms = 0;
429
0
                    model->bits[j] += 1;
430
0
                }
431
0
            }
432
0
        }
433
0
        model->state[j] = ms;
434
        /* If clr_fmt == YONLY, then we really only want to do
435
        this loop once, for j==0. */
436
0
        if (image->use_clr_fmt == 0/*YONLY*/)
437
0
            break;
438
0
    }
439
0
}
440
441
void _jxr_InitializeCountCBPLP(jxr_image_t image)
442
0
{
443
0
    image->count_max_CBPLP = 1;
444
0
    image->count_zero_CBPLP = 1;
445
0
}
446
447
void _jxr_UpdateCountCBPLP(jxr_image_t image, int cbplp, int max)
448
0
{
449
0
    image->count_zero_CBPLP += 1;
450
0
    if (cbplp == 0)
451
0
        image->count_zero_CBPLP -= 4;
452
0
    if (image->count_zero_CBPLP > 7)
453
0
        image->count_zero_CBPLP = 7;
454
0
    if (image->count_zero_CBPLP < -8)
455
0
        image->count_zero_CBPLP = -8;
456
457
0
    image->count_max_CBPLP += 1;
458
0
    if (cbplp == max)
459
0
        image->count_max_CBPLP -= 4;
460
0
    if (image->count_max_CBPLP > 7)
461
0
        image->count_max_CBPLP = 7;
462
0
    if (image->count_max_CBPLP < -8)
463
0
        image->count_max_CBPLP = -8;
464
0
}
465
466
void _jxr_InitLPVLC(jxr_image_t image)
467
0
{
468
0
    DEBUG(" ... InitLPVLC\n");
469
0
    InitVLCTable2(image, DecFirstIndLPLum);
470
0
    InitVLCTable2(image, DecIndLPLum0);
471
0
    InitVLCTable2(image, DecIndLPLum1);
472
0
    InitVLCTable2(image, DecFirstIndLPChr);
473
0
    InitVLCTable2(image, DecIndLPChr0);
474
0
    InitVLCTable2(image, DecIndLPChr1);
475
476
0
    _jxr_InitVLCTable(image, AbsLevelIndLP0);
477
0
    _jxr_InitVLCTable(image, AbsLevelIndLP1);
478
0
}
479
480
void _jxr_InitializeAdaptiveScanLP(jxr_image_t image)
481
0
{
482
0
    static const int ScanOrderLP[15] = { 4, 1, 5,
483
0
        8, 2, 9, 6,
484
0
        12, 3, 10, 13,
485
0
        7, 14, 11, 15};
486
0
    int idx;
487
0
    for (idx = 0 ; idx < 15 ; idx += 1) {
488
0
        image->lopass_scanorder[idx] = ScanOrderLP[idx];
489
0
        image->lopass_scantotals[idx] = ScanTotals[idx];
490
0
    }
491
0
}
492
493
/*
494
*/
495
void _jxr_InitializeAdaptiveScanHP(jxr_image_t image)
496
0
{
497
0
    static const unsigned ScanOrderHor[15] ={ 4, 1, 5,
498
0
        8, 2, 9, 6,
499
0
        12, 3, 10, 13,
500
0
        7, 14, 11, 15};
501
0
    static const unsigned ScanOrderVer[15] ={ 1, 2, 5,
502
0
        4, 3, 6, 9,
503
0
        8, 7, 12, 15,
504
0
        13, 10, 11, 14};
505
0
    int idx;
506
0
    for (idx = 0 ; idx < 15 ; idx += 1) {
507
0
        image->hipass_hor_scanorder[idx] = ScanOrderHor[idx];
508
0
        image->hipass_hor_scantotals[idx] = ScanTotals[idx];
509
0
        image->hipass_ver_scanorder[idx] = ScanOrderVer[idx];
510
0
        image->hipass_ver_scantotals[idx] = ScanTotals[idx];
511
0
    }
512
0
}
513
514
void _jxr_InitializeCBPModel(jxr_image_t image)
515
0
{
516
0
    image->hp_cbp_model.state[0] = 0;
517
0
    image->hp_cbp_model.state[1] = 0;
518
0
    image->hp_cbp_model.count0[0] = -4;
519
0
    image->hp_cbp_model.count0[1] = -4;
520
0
    image->hp_cbp_model.count1[0] = 4;
521
0
    image->hp_cbp_model.count1[1] = 4;
522
0
}
523
524
void _jxr_InitHPVLC(jxr_image_t image)
525
0
{
526
0
    InitVLCTable2(image, DecFirstIndHPLum);
527
0
    InitVLCTable2(image, DecIndHPLum0);
528
0
    InitVLCTable2(image, DecIndHPLum1);
529
0
    InitVLCTable2(image, DecFirstIndHPChr);
530
0
    InitVLCTable2(image, DecIndHPChr0);
531
0
    InitVLCTable2(image, DecIndHPChr1);
532
533
0
    _jxr_InitVLCTable(image, AbsLevelIndHP0);
534
0
    _jxr_InitVLCTable(image, AbsLevelIndHP1);
535
536
    /* _jxr_InitVLCTable(image, DecNumCBP); */
537
    /* _jxr_InitVLCTable(image, DecNumBlkCBP); */
538
0
}
539
540
void _jxr_InitCBPVLC(jxr_image_t image)
541
0
{
542
0
    _jxr_InitVLCTable(image, DecNumCBP);
543
0
    _jxr_InitVLCTable(image, DecNumBlkCBP);
544
0
}
545
546
static int num_ones(int val)
547
0
{
548
0
    int cnt = 0;
549
550
0
    assert(val >= 0);
551
552
0
    while (val > 0) {
553
0
        if (val&1) cnt += 1;
554
0
        val >>= 1;
555
0
    }
556
0
    return cnt;
557
0
}
558
559
0
# define SAT(x) do { if ((x) > 15) (x)=15 ; else if ((x) < -16) (x)=-16; } while(0);
560
561
static void update_cbp_model(jxr_image_t image, int c1, int norig)
562
0
{
563
0
    const int ndiff = 3;
564
565
0
    struct cbp_model_s*hp_cbp_model = & (image->hp_cbp_model);
566
567
0
    hp_cbp_model->count0[c1] += norig - ndiff;
568
0
    SAT(hp_cbp_model->count0[c1]);
569
570
0
    hp_cbp_model->count1[c1] += 16 - norig - ndiff;
571
0
    SAT(hp_cbp_model->count1[c1]);
572
573
0
    if (hp_cbp_model->count0[c1] < 0) {
574
0
        if (hp_cbp_model->count0[c1] < hp_cbp_model->count1[c1])
575
0
            hp_cbp_model->state[c1] = 1;
576
0
        else
577
0
            hp_cbp_model->state[c1] = 2;
578
579
0
    } else if (hp_cbp_model->count1[c1] < 0) {
580
0
        hp_cbp_model->state[c1] = 2;
581
582
0
    } else {
583
0
        hp_cbp_model->state[c1] = 0;
584
0
    }
585
0
}
586
587
int _jxr_PredCBP444(jxr_image_t image, int*diff_cbp,
588
                    int channel, unsigned tx,
589
                    unsigned mx, unsigned my)
590
0
{
591
0
    int chroma_flag = 0;
592
0
    int cbp;
593
0
    int norig;
594
595
0
    if (channel > 0)
596
0
        chroma_flag = 1;
597
598
0
    DEBUG(" PredCBP444: Prediction mode = %d\n", image->hp_cbp_model.state[chroma_flag]);
599
0
    cbp = diff_cbp[channel];
600
0
    if (image->hp_cbp_model.state[chroma_flag] == 0) {
601
0
        if (mx == 0) {
602
0
            if (my == 0)
603
0
                cbp ^= 1;
604
0
            else
605
0
                cbp ^= (MACROBLK_UP1_HPCBP(image, channel, tx, mx)>>10)&1;
606
0
        } else {
607
0
            cbp ^= (MACROBLK_CUR_HPCBP(image, channel, tx, mx-1)>>5)&1;
608
0
        }
609
610
0
        cbp ^= 0x02 & (cbp<<1);
611
0
        cbp ^= 0x10 & (cbp<<3);
612
0
        cbp ^= 0x20 & (cbp<<1);
613
0
        cbp ^= (cbp&0x33) << 2;
614
0
        cbp ^= (cbp&0xcc) << 6;
615
0
        cbp ^= (cbp&0x3300) << 2;
616
617
0
    } else if (image->hp_cbp_model.state[chroma_flag] == 2) {
618
0
        cbp ^= 0xffff;
619
0
    }
620
621
0
    norig = num_ones(cbp);
622
0
    DEBUG(" PredCBP444: NOrig=%d, CBPModel.Count0/1[%d]= %d/%d\n", norig, chroma_flag,
623
0
        image->hp_cbp_model.count0[chroma_flag],
624
0
        image->hp_cbp_model.count1[chroma_flag]);
625
0
    update_cbp_model(image, chroma_flag, norig);
626
0
    DEBUG(" PredCBP444: ...becomes CBPModel.Count0/1[%d]= %d/%d, new state=%d\n",
627
0
        chroma_flag, image->hp_cbp_model.count0[chroma_flag],
628
0
        image->hp_cbp_model.count1[chroma_flag], image->hp_cbp_model.state[chroma_flag]);
629
0
    return cbp;
630
0
}
631
632
void _jxr_w_PredCBP444(jxr_image_t image, int ch, unsigned tx, unsigned mx, int my)
633
0
{
634
0
    int chroma_flag = 0;
635
0
    int cbp;
636
0
    int norig;
637
0
    if (ch > 0)
638
0
        chroma_flag = 1;
639
640
0
    DEBUG(" PredCBP444: Prediction mode = %d\n", image->hp_cbp_model.state[chroma_flag]);
641
0
    cbp = MACROBLK_UP1_HPCBP(image,ch,tx,mx);
642
0
    norig = num_ones(cbp);
643
644
0
    DEBUG(" PredCBP444: ... cbp starts as 0x%x\n", cbp);
645
646
0
    if (image->hp_cbp_model.state[chroma_flag] == 0) {
647
648
0
        cbp ^= (cbp&0x3300) << 2;
649
0
        cbp ^= (cbp&0xcc) << 6;
650
0
        cbp ^= (cbp&0x33) << 2;
651
0
        cbp ^= 0x20 & (cbp<<1);
652
0
        cbp ^= 0x10 & (cbp<<3);
653
0
        cbp ^= 0x02 & (cbp<<1);
654
655
0
        if (mx == 0) {
656
0
            if (my == 0)
657
0
                cbp ^= 1;
658
0
            else
659
0
                cbp ^= (MACROBLK_CUR_HPCBP(image,ch, tx, mx)>>10)&1;
660
0
        } else {
661
0
            cbp ^= (MACROBLK_UP1_HPCBP(image,ch, tx, mx-1)>>5)&1;
662
0
        }
663
664
665
0
    } else if (image->hp_cbp_model.state[chroma_flag] == 2){
666
0
        cbp ^= 0xffff;
667
0
    }
668
669
0
    DEBUG(" PredCBP444: ... diff_cbp 0x%04x\n", cbp);
670
0
    MACROBLK_UP1(image,ch,tx,mx).hp_diff_cbp = cbp;
671
672
0
    update_cbp_model(image, chroma_flag, norig);
673
0
}
674
675
int _jxr_PredCBP422(jxr_image_t image, int*diff_cbp,
676
                    int channel, unsigned tx,
677
                    unsigned mx, unsigned my)
678
0
{
679
0
    int cbp;
680
0
    int norig;
681
682
0
    assert(channel > 0);
683
0
    DEBUG(" PredCBP422: Prediction mode = %d, channel=%d, cbp_mode.State[1]=%d\n",
684
0
        image->hp_cbp_model.state[1], channel, image->hp_cbp_model.state[1]);
685
0
    cbp = diff_cbp[channel];
686
687
0
    if (image->hp_cbp_model.state[1] == 0) {
688
0
        if (mx == 0) {
689
0
            if (my == 0)
690
0
                cbp ^= 1;
691
0
            else
692
0
                cbp ^= (MACROBLK_UP1_HPCBP(image, channel, tx, mx)>>6)&1;
693
0
        } else {
694
0
            cbp ^= (MACROBLK_CUR_HPCBP(image, channel, tx, mx-1)>>1)&1;
695
0
        }
696
697
0
        cbp ^= 0x02 & (cbp<<1);
698
0
        cbp ^= 0x0c & (cbp<<2);
699
0
        cbp ^= 0x30 & (cbp<<2);
700
0
        cbp ^= 0xc0 & (cbp<<2);
701
0
    } else if (image->hp_cbp_model.state[1] == 2) {
702
0
        cbp ^= 0xff;
703
0
    }
704
705
0
    norig = num_ones(cbp) * 2;
706
0
    update_cbp_model(image, 1, norig);
707
708
0
    return cbp;
709
0
}
710
711
void _jxr_w_PredCBP422(jxr_image_t image, int ch, unsigned tx, unsigned mx, int my)
712
0
{
713
0
    int cbp;
714
0
    int norig;
715
716
0
    assert(ch > 0);
717
0
    DEBUG(" PredCBP422: Prediction mode = %d\n", image->hp_cbp_model.state[1]);
718
0
    cbp = MACROBLK_UP1_HPCBP(image,ch,tx,mx);
719
0
    norig = num_ones(cbp) * 2;
720
721
0
    DEBUG(" PredCBP422: ... cbp[%d] starts as 0x%x\n", ch, cbp);
722
723
0
    if (image->hp_cbp_model.state[1] == 0) {
724
725
0
        cbp ^= 0xc0 & (cbp<<2);
726
0
        cbp ^= 0x30 & (cbp<<2);
727
0
        cbp ^= 0x0c & (cbp<<2);
728
0
        cbp ^= 0x02 & (cbp<<1);
729
730
0
        if (mx == 0) {
731
0
            if (my == 0)
732
0
                cbp ^= 1;
733
0
            else
734
0
                cbp ^= (MACROBLK_CUR_HPCBP(image, ch, tx, mx)>>6)&1;
735
0
        } else {
736
0
            cbp ^= (MACROBLK_UP1_HPCBP(image, ch, tx, mx-1)>>1)&1;
737
0
        }
738
739
0
    } else if (image->hp_cbp_model.state[1] == 2) {
740
0
        cbp ^= 0xff;
741
0
    }
742
743
0
    DEBUG(" PredCBP422: ... diff_cbp 0x%04x\n", cbp);
744
0
    MACROBLK_UP1(image,ch,tx,mx).hp_diff_cbp = cbp;
745
746
0
    update_cbp_model(image, 1, norig);
747
0
}
748
749
750
int _jxr_PredCBP420(jxr_image_t image, int*diff_cbp,
751
                    int channel, unsigned tx,
752
                    unsigned mx, unsigned my)
753
0
{
754
0
    int cbp;
755
0
    int norig;
756
0
    assert(channel > 0);
757
0
    DEBUG(" PredCBP420: Prediction mode = %d, channel=%d, cbp_mode.State[1]=%d\n",
758
0
        image->hp_cbp_model.state[1], channel, image->hp_cbp_model.state[1]);
759
0
    cbp = diff_cbp[channel];
760
761
0
    if (image->hp_cbp_model.state[1] == 0) {
762
0
        if (mx == 0) {
763
0
            if (my == 0)
764
0
                cbp ^= 1;
765
0
            else
766
0
                cbp ^= (MACROBLK_UP1_HPCBP(image, channel, tx, mx)>>2)&1;
767
0
        } else {
768
0
            cbp ^= (MACROBLK_CUR_HPCBP(image, channel, tx, mx-1)>>1)&1;
769
0
        }
770
771
0
        cbp ^= 0x02 & (cbp<<1);
772
0
        cbp ^= 0x0c & (cbp<<2);
773
0
    } else if (image->hp_cbp_model.state[1] == 2) {
774
0
        cbp ^= 0xf;
775
0
    }
776
777
0
    norig = num_ones(cbp) * 4;
778
0
    update_cbp_model(image, 1, norig);
779
780
0
    return cbp;
781
0
}
782
783
void _jxr_w_PredCBP420(jxr_image_t image, int ch, unsigned tx, unsigned mx, int my)
784
0
{
785
0
    int cbp;
786
0
    int norig;
787
0
    assert(ch > 0);
788
0
    DEBUG(" PredCBP420: Prediction mode = %d\n", image->hp_cbp_model.state[1]);
789
0
    cbp = MACROBLK_UP1_HPCBP(image,ch,tx,mx);
790
0
    norig = num_ones(cbp) * 4;
791
792
0
    DEBUG(" PredCBP420: ... cbp[%d] starts as 0x%x\n", ch, cbp);
793
794
0
    if (image->hp_cbp_model.state[1] == 0) {
795
796
0
        cbp ^= 0x0c & (cbp<<2);
797
0
        cbp ^= 0x02 & (cbp<<1);
798
799
0
        if (mx == 0) {
800
0
            if (my == 0)
801
0
                cbp ^= 1;
802
0
            else
803
0
                cbp ^= (MACROBLK_CUR_HPCBP(image, ch, tx, mx)>>2)&1;
804
0
        } else {
805
0
            cbp ^= (MACROBLK_UP1_HPCBP(image, ch, tx, mx-1)>>1)&1;
806
0
        }
807
808
0
    } else if (image->hp_cbp_model.state[1] == 2) {
809
0
        cbp ^= 0xf;
810
0
    }
811
812
0
    DEBUG(" PredCBP420: ... diff_cbp 0x%04x\n", cbp);
813
0
    MACROBLK_UP1(image,ch,tx,mx).hp_diff_cbp = cbp;
814
815
0
    update_cbp_model(image, 1, norig);
816
0
}
817
818
void _jxr_ResetTotalsAdaptiveScanLP(jxr_image_t image)
819
0
{
820
0
    int idx;
821
0
    for (idx = 0 ; idx < 15 ; idx += 1) {
822
0
        image->lopass_scantotals[idx] = ScanTotals[idx];
823
0
    }
824
0
}
825
826
void _jxr_ResetTotalsAdaptiveScanHP(jxr_image_t image)
827
0
{
828
0
    int idx;
829
0
    for (idx = 0 ; idx < 15 ; idx += 1) {
830
0
        image->hipass_hor_scantotals[idx] = ScanTotals[idx];
831
0
        image->hipass_ver_scantotals[idx] = ScanTotals[idx];
832
0
    }
833
0
}
834
835
static int
836
calculate_mbdc_mode(jxr_image_t image, int tx, int mx, int my)
837
0
{
838
0
    long left;
839
0
    long top;
840
0
    long topleft;
841
0
    long strhor;
842
0
    long strvert;
843
844
0
    if (mx == 0 && my == 0)
845
0
        return 3; /* No prediction. */
846
847
0
    if (mx == 0)
848
0
        return 1; /* Predictions from top only. */
849
850
0
    if (my == 0)
851
0
        return 0; /* prediction from left only */
852
853
0
    left = MACROBLK_CUR_DC(image, 0, tx, mx-1);
854
0
    top = MACROBLK_UP_DC(image, 0, tx, mx);
855
0
    topleft = MACROBLK_UP_DC(image, 0, tx, mx-1);
856
857
0
    strhor = 0;
858
0
    strvert = 0;
859
0
    if (image->use_clr_fmt==0 || image->use_clr_fmt==6) {/* YONLY or NCOMPONENT */
860
861
0
        strhor = labs(topleft - left);
862
0
        strvert = labs(topleft - top);
863
0
    } else {
864
0
        long left_u = MACROBLK_CUR_DC(image, 1, tx, mx-1);
865
0
        long top_u = MACROBLK_UP_DC(image, 1, tx, mx);
866
0
        long topleft_u = MACROBLK_UP_DC(image, 1, tx, mx-1);
867
0
        long left_v = MACROBLK_CUR_DC(image, 2, tx, mx-1);
868
0
        long top_v = MACROBLK_UP_DC(image, 2, tx, mx);
869
0
        long topleft_v = MACROBLK_UP_DC(image, 2, tx, mx-1);
870
871
0
        long scale = 2;
872
0
        if (image->use_clr_fmt == 2 /*YUV422*/)
873
0
            scale = 4;
874
0
        if (image->use_clr_fmt == 1 /*YUV420*/)
875
0
            scale = 8;
876
877
0
        strhor = labs(topleft - left)*scale + labs(topleft_u - left_u) + labs(topleft_v - left_v);
878
0
        strvert = labs(topleft - top)*scale + labs(topleft_u - top_u) + labs(topleft_v - top_v);
879
0
    }
880
881
0
    if ((strhor*4) < strvert)
882
0
        return 1;
883
884
0
    if ((strvert*4) < strhor)
885
0
        return 0;
886
887
0
    return 2;
888
0
}
889
890
static void predict_lp444(jxr_image_t image, int tx, int mx, int my, int ch, int mblp_mode);
891
static void predict_lp422(jxr_image_t image, int tx, int mx, int my, int ch, int mblp_mode, int mbdc_mode);
892
static void predict_lp420(jxr_image_t image, int tx, int mx, int my, int ch, int mblp_mode);
893
894
void _jxr_complete_cur_dclp(jxr_image_t image, int tx, int mx, int my)
895
0
{
896
    /* Calculate the mbcd prediction mode. This mode is used for
897
    all the planes of DC data. */
898
0
    int mbdc_mode = calculate_mbdc_mode(image, tx, mx, image->cur_my);
899
0
    int mblp_mode;
900
    /* Now process all the planes of DC data. */
901
0
    int ch;
902
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
903
0
        long left = mx>0? MACROBLK_CUR_DC(image,ch,tx,mx-1) : 0;
904
0
        long top = MACROBLK_UP_DC(image,ch,tx,mx);
905
906
0
        DEBUG(" MBDC_MODE=%d for TX=%d, MBx=%d, MBy=%d (cur_my=%d), ch=%d, left=0x%lx, top=0x%lx, cur=0x%x\n",
907
0
            mbdc_mode, tx, mx, my, image->cur_my, ch, left, top, MACROBLK_CUR_DC(image,ch,tx,mx));
908
909
0
        MACROBLK_CUR(image,ch,tx,mx).pred_dclp[0] = MACROBLK_CUR_DC(image,ch,tx,mx);
910
0
        CHECK1(image->lwf_test, MACROBLK_CUR_DC(image,ch,tx,mx));
911
0
        switch (mbdc_mode) {
912
0
            case 0: /* left */
913
0
                MACROBLK_CUR_DC(image,ch,tx,mx) += left;
914
0
                break;
915
0
            case 1: /* top */
916
0
                MACROBLK_CUR_DC(image,ch,tx,mx) += top;
917
0
                break;
918
0
            case 2:/* top and left */
919
                /* Note that we really MEAN >>1 and NOT /2. in
920
                particular, if the sum is -1, we want the
921
                result to also be -1. That extra stuff after
922
                the "|" is there to make sure the sign bit is
923
                not lost. Also, the chroma planes for YUV42X
924
                formats round *up* the mean, where all other
925
                planes round down. */
926
0
                if (ch>0 && (image->use_clr_fmt==1/*YUV420*/||image->use_clr_fmt==2/*YUV422*/))
927
0
                    MACROBLK_CUR_DC(image,ch,tx,mx) += (left+top+1) >> 1 | ((left+top+1)&~INT_MAX);
928
0
                else
929
0
                    MACROBLK_CUR_DC(image,ch,tx,mx) += (left+top) >> 1 | ((left+top)&~INT_MAX);
930
0
                break;
931
0
            default:
932
0
                break;
933
0
        }
934
0
    }
935
936
0
    mblp_mode = 0;
937
0
    if (mbdc_mode==0 && MACROBLK_CUR_LP_QUANT(image,0,tx,mx) == MACROBLK_CUR_LP_QUANT(image,0,tx,mx-1)) {
938
0
        mblp_mode = 0;
939
0
    } else if (mbdc_mode==1 && MACROBLK_CUR_LP_QUANT(image,0,tx,mx) == MACROBLK_UP1_LP_QUANT(image,0,tx,mx)) {
940
0
        mblp_mode = 1;
941
942
0
    } else {
943
0
        mblp_mode = 2;
944
0
    }
945
946
0
    DEBUG(" MBLP_MODE=%d for MBx=%d, MBy=%d (lp_quant=%d,lp_quant_ctx=%d)\n", mblp_mode, mx, image->cur_my,
947
0
        MACROBLK_CUR_LP_QUANT(image,0,tx,mx),
948
0
        mbdc_mode==0? MACROBLK_CUR_LP_QUANT(image,0,tx,mx-1) : mbdc_mode==1 ? MACROBLK_UP1_LP_QUANT(image,0,tx,mx) : -1);
949
950
0
    predict_lp444(image, tx, mx, my, 0, mblp_mode);
951
0
    for (ch = 1 ; ch < image->num_channels ; ch += 1) {
952
0
        switch (image->use_clr_fmt) {
953
0
            case 1: /* YUV420 */
954
0
                predict_lp420(image, tx, mx, my, ch, mblp_mode);
955
0
                break;
956
0
            case 2: /* YUV422 */
957
0
                predict_lp422(image, tx, mx, my, ch, mblp_mode, mbdc_mode);
958
0
                break;
959
0
            default:
960
0
                predict_lp444(image,tx, mx, my, ch, mblp_mode);
961
0
                break;
962
0
        }
963
0
    }
964
0
}
965
966
static void predict_lp444(jxr_image_t image, int tx, int mx, int my, int ch, int mblp_mode)
967
0
{
968
#if defined(DETAILED_DEBUG)
969
    {
970
        int jdx;
971
        DEBUG(" DC/LP (strip=%3d, mbx=%4d, ch=%d) Difference:", my, mx, ch);
972
        DEBUG(" 0x%08x", MACROBLK_CUR(image,ch,tx,mx).pred_dclp[0]);
973
        for (jdx = 0; jdx < 15 ; jdx += 1) {
974
            DEBUG(" 0x%08x", MACROBLK_CUR_LP(image,ch,tx,mx,jdx));
975
            if ((jdx+1)%4 == 3 && jdx != 14)
976
                DEBUG("\n%*s:", 46, "");
977
        }
978
        DEBUG("\n");
979
    }
980
#endif
981
982
0
    switch (mblp_mode) {
983
0
        case 0: /* left */
984
0
            CHECK3(image->lwf_test, MACROBLK_CUR_LP(image,ch,tx,mx,3), MACROBLK_CUR_LP(image,ch,tx,mx,7), MACROBLK_CUR_LP(image,ch,tx,mx,11));
985
0
            MACROBLK_CUR_LP(image,ch,tx,mx,3) += MACROBLK_CUR(image,ch,tx,mx-1).pred_dclp[4];
986
0
            MACROBLK_CUR_LP(image,ch,tx,mx,7) += MACROBLK_CUR(image,ch,tx,mx-1).pred_dclp[5];
987
0
            MACROBLK_CUR_LP(image,ch,tx,mx,11)+= MACROBLK_CUR(image,ch,tx,mx-1).pred_dclp[6];
988
0
            break;
989
0
        case 1: /* up */
990
0
            CHECK3(image->lwf_test, MACROBLK_CUR_LP(image,ch,tx,mx,0), MACROBLK_CUR_LP(image,ch,tx,mx,1), MACROBLK_CUR_LP(image,ch,tx,mx,2));
991
0
            MACROBLK_CUR_LP(image,ch,tx,mx,0) += MACROBLK_UP1(image,ch,tx,mx).pred_dclp[1];
992
0
            MACROBLK_CUR_LP(image,ch,tx,mx,1) += MACROBLK_UP1(image,ch,tx,mx).pred_dclp[2];
993
0
            MACROBLK_CUR_LP(image,ch,tx,mx,2) += MACROBLK_UP1(image,ch,tx,mx).pred_dclp[3];
994
0
            break;
995
0
        case 2:
996
0
            break;
997
0
    }
998
999
#if defined(DETAILED_DEBUG)
1000
    {
1001
        int jdx;
1002
        DEBUG(" DC/LP (strip=%3d, mbx=%4d, ch=%d) Predicted:", my, mx, ch);
1003
        DEBUG(" 0x%08x", MACROBLK_CUR_DC(image,ch,tx,mx));
1004
        for (jdx = 0; jdx < 15 ; jdx += 1) {
1005
            DEBUG(" 0x%08x", MACROBLK_CUR_LP(image,ch,tx,mx,jdx));
1006
            if ((jdx+1)%4 == 3 && jdx != 14)
1007
                DEBUG("\n%*s:", 45, "");
1008
        }
1009
        DEBUG("\n");
1010
    }
1011
#endif
1012
1013
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[1] = MACROBLK_CUR_LP(image,ch,tx,mx,0);
1014
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[2] = MACROBLK_CUR_LP(image,ch,tx,mx,1);
1015
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[3] = MACROBLK_CUR_LP(image,ch,tx,mx,2);
1016
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[4] = MACROBLK_CUR_LP(image,ch,tx,mx,3);
1017
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[5] = MACROBLK_CUR_LP(image,ch,tx,mx,7);
1018
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[6] = MACROBLK_CUR_LP(image,ch,tx,mx,11);
1019
0
}
1020
1021
static void predict_lp422(jxr_image_t image, int tx, int mx, int my, int ch, int mblp_mode, int mbdc_mode)
1022
0
{
1023
#if defined(DETAILED_DEBUG)
1024
    {
1025
        int jdx;
1026
        DEBUG(" DC/LP (strip=%3d, tx=%d, mbx=%4d, ch=%d) Difference:", my, tx, mx, ch);
1027
        DEBUG(" 0x%08x", MACROBLK_CUR(image,ch,tx,mx).pred_dclp[0]);
1028
        for (jdx = 0; jdx < 7 ; jdx += 1) {
1029
            DEBUG(" 0x%08x", MACROBLK_CUR_LP(image,ch,tx,mx,jdx));
1030
            if ((jdx+1)%4 == 3 && jdx != 6)
1031
                DEBUG("\n%*s:", 52, "");
1032
        }
1033
        DEBUG("\n");
1034
    }
1035
#endif
1036
1037
0
    switch (mblp_mode) {
1038
0
case 0: /* left */
1039
0
    CHECK3(image->lwf_test, MACROBLK_CUR_LP(image,ch,tx,mx,3), MACROBLK_CUR_LP(image,ch,tx,mx,1), MACROBLK_CUR_LP(image,ch,tx,mx,5));
1040
0
    MACROBLK_CUR_LP(image,ch,tx,mx,3) += MACROBLK_CUR(image,ch,tx,mx-1).pred_dclp[4];
1041
0
    MACROBLK_CUR_LP(image,ch,tx,mx,1) += MACROBLK_CUR(image,ch,tx,mx-1).pred_dclp[2];
1042
0
    MACROBLK_CUR_LP(image,ch,tx,mx,5) += MACROBLK_CUR(image,ch,tx,mx-1).pred_dclp[6];
1043
0
    break;
1044
0
case 1: /* up */
1045
0
    CHECK3(image->lwf_test, MACROBLK_CUR_LP(image,ch,tx,mx,3), MACROBLK_CUR_LP(image,ch,tx,mx,0), MACROBLK_CUR_LP(image,ch,tx,mx,4));
1046
0
    MACROBLK_CUR_LP(image,ch,tx,mx,3) += MACROBLK_UP1(image,ch,tx,mx).pred_dclp[4];
1047
0
    MACROBLK_CUR_LP(image,ch,tx,mx,0) += MACROBLK_UP1(image,ch,tx,mx).pred_dclp[5];
1048
0
    MACROBLK_CUR_LP(image,ch,tx,mx,4) += MACROBLK_CUR_LP(image,ch,tx,mx,0);
1049
0
    break;
1050
0
case 2:
1051
0
    if (mbdc_mode == 1)
1052
0
    {
1053
0
        CHECK1(image->lwf_test, MACROBLK_CUR_LP(image,ch,tx,mx,4));
1054
0
        MACROBLK_CUR_LP(image,ch,tx,mx,4) += MACROBLK_CUR_LP(image,ch,tx,mx,0);
1055
0
    }
1056
0
    break;
1057
0
    }
1058
1059
#if defined(DETAILED_DEBUG)
1060
    {
1061
        int jdx;
1062
        DEBUG(" DC/LP (strip=%3d, tx=%d, mbx=%4d, ch=%d) Predicted:", my, tx, mx, ch);
1063
        DEBUG(" 0x%08x", MACROBLK_CUR_DC(image,ch,tx,mx));
1064
        for (jdx = 0; jdx < 7 ; jdx += 1) {
1065
            DEBUG(" 0x%08x", MACROBLK_CUR_LP(image,ch,tx,mx,jdx));
1066
            if ((jdx+1)%4 == 3 && jdx != 6)
1067
                DEBUG("\n%*s:", 51, "");
1068
        }
1069
        DEBUG("\n");
1070
    }
1071
#endif
1072
1073
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[1] = MACROBLK_CUR_LP(image,ch,tx,mx,0);
1074
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[2] = MACROBLK_CUR_LP(image,ch,tx,mx,1);
1075
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[4] = MACROBLK_CUR_LP(image,ch,tx,mx,3);
1076
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[5] = MACROBLK_CUR_LP(image,ch,tx,mx,4);
1077
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[6] = MACROBLK_CUR_LP(image,ch,tx,mx,5);
1078
0
}
1079
1080
static void predict_lp420(jxr_image_t image, int tx, int mx, int my, int ch, int mblp_mode)
1081
0
{
1082
0
    switch (mblp_mode) {
1083
0
        case 0: /* left */
1084
0
            CHECK1(image->lwf_test, MACROBLK_CUR_LP(image,ch,tx,mx,1));
1085
0
            MACROBLK_CUR_LP(image,ch,tx,mx,1) += MACROBLK_CUR(image,ch,tx,mx-1).pred_dclp[2];
1086
0
            break;
1087
0
        case 1: /* up */
1088
0
            CHECK1(image->lwf_test, MACROBLK_CUR_LP(image,ch,tx,mx,0));
1089
0
            MACROBLK_CUR_LP(image,ch,tx,mx,0) += MACROBLK_UP1(image,ch,tx,mx).pred_dclp[1];
1090
0
            break;
1091
0
    }
1092
1093
#if defined(DETAILED_DEBUG)
1094
    {
1095
        int jdx;
1096
        DEBUG(" DC/LP (strip=%3d, tx=%d, mbx=%4d, ch=%d) Predicted:", tx, my, mx, ch);
1097
        DEBUG(" 0x%08x", MACROBLK_CUR_DC(image,ch,tx,mx));
1098
        for (jdx = 0; jdx < 3 ; jdx += 1) {
1099
            DEBUG(" 0x%08x", MACROBLK_CUR_LP(image,ch,tx,mx,jdx));
1100
        }
1101
        DEBUG("\n");
1102
    }
1103
#endif
1104
1105
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[1] = MACROBLK_CUR_LP(image,ch,tx,mx,0);
1106
0
    MACROBLK_CUR(image,ch,tx,mx).pred_dclp[2] = MACROBLK_CUR_LP(image,ch,tx,mx,1);
1107
0
}
1108
1109
/*
1110
* TRANSFORM functions, forward and inverse.
1111
*/
1112
static void _InvPermute(int*coeff)
1113
0
{
1114
0
    static const int inverse[16] = {0, 8, 4, 13,
1115
0
        2, 15, 3, 14,
1116
0
        1, 12, 5, 9,
1117
0
        7, 11, 6, 10};
1118
0
    int t[16];
1119
0
    int idx;
1120
1121
0
    for (idx = 0 ; idx < 16 ; idx += 1)
1122
0
        t[inverse[idx]] = coeff[idx];
1123
0
    for (idx = 0 ; idx < 16 ; idx += 1)
1124
0
        coeff[idx] = t[idx];
1125
0
}
1126
1127
static void _FwdPermute(int*coeff)
1128
0
{
1129
0
    static const int fwd[16] = {0, 8, 4, 6,
1130
0
        2, 10, 14, 12,
1131
0
        1, 11, 15, 13,
1132
0
        9, 3, 7, 5};
1133
1134
0
    int t[16];
1135
0
    int idx;
1136
0
    for (idx = 0 ; idx < 16 ; idx += 1)
1137
0
        t[fwd[idx]] = coeff[idx];
1138
0
    for (idx = 0 ; idx < 16 ; idx += 1)
1139
0
        coeff[idx] = t[idx];
1140
0
}
1141
1142
static void _2x2T_h(int*a, int*b, int*c, int*d, int R_flag)
1143
0
{
1144
0
    int t1;
1145
0
    int t2;
1146
0
    *a += *d;
1147
0
    *b -= *c;
1148
1149
0
    t1 = ((*a - *b + R_flag) >> 1);
1150
0
    t2 = *c;
1151
1152
0
    *c = t1 - *d;
1153
0
    *d = t1 - t2;
1154
0
    CHECK5(long_word_flag, *a, *b, t1, *c, *d);
1155
0
    *a -= *d;
1156
0
    *b += *c;
1157
0
    CHECK2(long_word_flag, *a, *b);
1158
0
}
1159
1160
static void _2x2T_h_POST(int*a, int*b, int*c, int*d)
1161
0
{
1162
0
    int t1;
1163
0
    *b -= *c;
1164
0
    *a += (*d * 3 + 4) >> 3;
1165
0
    *d -= *b >> 1;
1166
0
    t1 = ((*a - *b) >> 1) - *c;
1167
0
    CHECK4(long_word_flag, *b, *a, *d, t1);
1168
0
    *c = *d;
1169
0
    *d = t1;
1170
0
    *a -= *d;
1171
0
    *b += *c;
1172
0
    CHECK2(long_word_flag, *a, *b);
1173
0
}
1174
1175
static void _2x2T_h_Enc(int*a, int*b, int*c, int*d)
1176
0
{
1177
0
    int t1;
1178
0
    int t2;
1179
0
    *a += *d;
1180
0
    *b -= *c;
1181
0
    CHECK2(long_word_flag, *a, *b);
1182
0
    t1 = *d;
1183
0
    t2 = *c;
1184
0
    *c = ((*a - *b) >> 1) - t1;
1185
0
    *d = t2 + (*b >> 1);
1186
0
    *b += *c;
1187
0
    *a -= (*d * 3 + 4) >> 3;
1188
0
    CHECK4(long_word_flag, *c, *d, *b, *a);
1189
0
}
1190
1191
static void _InvT_odd(int*a, int*b, int*c, int*d)
1192
0
{
1193
0
    *b += *d;
1194
0
    *a -= *c;
1195
0
    *d -= *b >> 1;
1196
0
    *c += (*a + 1) >> 1;
1197
0
    CHECK4(long_word_flag, *a, *b, *c, *d);
1198
1199
0
    *a -= ((*b)*3 + 4) >> 3;
1200
0
    *b += ((*a)*3 + 4) >> 3;
1201
0
    *c -= ((*d)*3 + 4) >> 3;
1202
0
    *d += ((*c)*3 + 4) >> 3;
1203
0
    CHECK4(long_word_flag, *a, *b, *c, *d);
1204
1205
0
    *c -= (*b + 1) >> 1;
1206
0
    *d = ((*a + 1) >> 1) - *d;
1207
0
    *b += *c;
1208
0
    *a -= *d;
1209
0
    CHECK4(long_word_flag, *a, *b, *c, *d);
1210
0
}
1211
1212
static void _InvT_odd_odd(int*a, int*b, int*c, int*d)
1213
0
{
1214
0
    int t1, t2;
1215
0
    *d += *a;
1216
0
    *c -= *b;
1217
0
    t1 = *d >> 1;
1218
0
    t2 = *c >> 1;
1219
0
    *a -= t1;
1220
0
    *b += t2;
1221
0
    CHECK4(long_word_flag, *a, *b, *c, *d);
1222
1223
0
    *a -= ((*b)*3 + 3) >> 3;
1224
0
    *b += ((*a)*3 + 3) >> 2;
1225
0
    CHECK2(long_word_flag, *a, *b);
1226
0
    *a -= ((*b)*3 + 4) >> 3;
1227
1228
0
    *b -= t2;
1229
0
    CHECK2(long_word_flag, *a, *b);
1230
0
    *a += t1;
1231
0
    *c += *b;
1232
0
    *d -= *a;
1233
1234
0
    *b = -*b;
1235
0
    *c = -*c;
1236
0
    CHECK4(long_word_flag, *a, *b, *c, *d);
1237
0
}
1238
1239
static void _InvT_odd_odd_POST(int*a, int*b, int*c, int*d)
1240
0
{
1241
0
    int t1, t2;
1242
1243
0
    *d += *a;
1244
0
    *c -= *b;
1245
0
    t1 = *d >> 1;
1246
0
    t2 = *c >> 1;
1247
0
    *a -= t1;
1248
0
    *b += t2;
1249
0
    CHECK4(long_word_flag, *d, *c, *a, *b);
1250
1251
0
    *a -= (*b * 3 + 6) >> 3;
1252
0
    *b += (*a * 3 + 2) >> 2;
1253
0
    CHECK2(long_word_flag, *a, *b);
1254
0
    *a -= (*b * 3 + 4) >> 3;
1255
1256
0
    *b -= t2;
1257
0
    CHECK2(long_word_flag, *a, *b);
1258
0
    *a += t1;
1259
0
    *c += *b;
1260
0
    *d -= *a;
1261
0
    CHECK3(long_word_flag, *a, *c, *d);
1262
0
}
1263
1264
static void _T_odd(int*a, int*b, int*c, int*d)
1265
0
{
1266
0
    *b -= *c;
1267
0
    *a += *d;
1268
0
    *c += (*b + 1) >> 1;
1269
0
    *d = ((*a + 1) >> 1) - *d;
1270
0
    CHECK4(long_word_flag, *b, *a, *c, *d);
1271
1272
0
    *b -= (*a * 3 + 4) >> 3;
1273
0
    *a += (*b * 3 + 4) >> 3;
1274
0
    *d -= (*c * 3 + 4) >> 3;
1275
0
    *c += (*d * 3 + 4) >> 3;
1276
0
    CHECK4(long_word_flag, *b, *a, *d, *c);
1277
1278
0
    *d += *b >> 1;
1279
0
    *c -= (*a + 1) >> 1;
1280
0
    *b -= *d;
1281
0
    *a += *c;
1282
0
    CHECK4(long_word_flag, *d, *c, *b, *a);
1283
0
}
1284
1285
static void _T_odd_odd(int*a, int*b, int*c, int*d)
1286
0
{
1287
0
    int t1;
1288
0
    int t2;
1289
0
    *b = -*b;
1290
0
    *c = -*c;
1291
0
    CHECK2(long_word_flag, *b, *c);
1292
1293
0
    *d += *a;
1294
0
    *c -= *b;
1295
0
    t1 = *d >> 1;
1296
0
    t2 = *c >> 1;
1297
0
    *a -= t1;
1298
0
    *b += t2;
1299
0
    CHECK4(long_word_flag, *d, *c, *a, *b);
1300
1301
0
    *a += (*b * 3 + 4) >> 3;
1302
0
    *b -= (*a * 3 + 3) >> 2;
1303
0
    CHECK2(long_word_flag, *a, *b);
1304
0
    *a += (*b * 3 + 3) >> 3;
1305
1306
0
    *b -= t2;
1307
0
    CHECK2(long_word_flag, *a, *b);
1308
0
    *a += t1;
1309
0
    *c += *b;
1310
0
    *d -= *a;
1311
0
    CHECK3(long_word_flag, *a, *c, *d);
1312
0
}
1313
1314
void _jxr_InvPermute2pt(int*a, int*b)
1315
0
{
1316
0
    int t1 = *a;
1317
0
    *a = *b;
1318
0
    *b = t1;
1319
0
}
1320
1321
void _jxr_2ptT(int*a, int*b)
1322
0
{
1323
0
    *a -= (*b + 1) >> 1;
1324
0
    *b += *a;
1325
0
    CHECK2(long_word_flag, *a, *b);
1326
0
}
1327
1328
/* This is the inverse of the 2ptT function */
1329
void _jxr_2ptFwdT(int*a, int*b)
1330
0
{
1331
0
    *b -= *a;
1332
0
    *a += (*b + 1) >> 1;
1333
0
    CHECK2(long_word_flag, *b, *a);
1334
0
}
1335
1336
void _jxr_2x2IPCT(int*coeff)
1337
0
{
1338
0
    _2x2T_h(coeff+0, coeff+1, coeff+2, coeff+3, 0);
1339
    /* _2x2T_h(coeff+0, coeff+2, coeff+1, coeff+3, 0); */
1340
0
}
1341
1342
void _jxr_4x4IPCT(int*coeff)
1343
0
{
1344
    /* Permute */
1345
0
    _InvPermute(coeff);
1346
1347
#if defined(DETAILED_DEBUG) && 0
1348
    {
1349
        int idx;
1350
        DEBUG(" InvPermute:\n%*s", 4, "");
1351
        for (idx = 0 ; idx < 16 ; idx += 1) {
1352
            DEBUG(" 0x%08x", coeff[idx]);
1353
            if (idx%4 == 3 && idx != 15)
1354
                DEBUG("\n%*s", 4, "");
1355
        }
1356
        DEBUG("\n");
1357
    }
1358
#endif
1359
0
    _2x2T_h (coeff+0, coeff+ 1, coeff+4, coeff+ 5, 1);
1360
0
    _InvT_odd(coeff+2, coeff+ 3, coeff+6, coeff+ 7);
1361
0
    _InvT_odd(coeff+8, coeff+12, coeff+9, coeff+13);
1362
0
    _InvT_odd_odd(coeff+10, coeff+11, coeff+14, coeff+15);
1363
#if defined(DETAILED_DEBUG) && 0
1364
    {
1365
        int idx;
1366
        DEBUG(" stage 1:\n%*s", 4, "");
1367
        for (idx = 0 ; idx < 16 ; idx += 1) {
1368
            DEBUG(" 0x%08x", coeff[idx]);
1369
            if (idx%4 == 3 && idx != 15)
1370
                DEBUG("\n%*s", 4, "");
1371
        }
1372
        DEBUG("\n");
1373
    }
1374
#endif
1375
1376
0
    _2x2T_h(coeff+0, coeff+3, coeff+12, coeff+15, 0);
1377
0
    _2x2T_h(coeff+5, coeff+6, coeff+ 9, coeff+10, 0);
1378
0
    _2x2T_h(coeff+1, coeff+2, coeff+13, coeff+14, 0);
1379
0
    _2x2T_h(coeff+4, coeff+7, coeff+ 8, coeff+11, 0);
1380
0
}
1381
1382
void _jxr_4x4PCT(int*coeff)
1383
0
{
1384
0
    _2x2T_h(coeff+0, coeff+3, coeff+12, coeff+15, 0);
1385
0
    _2x2T_h(coeff+5, coeff+6, coeff+ 9, coeff+10, 0);
1386
0
    _2x2T_h(coeff+1, coeff+2, coeff+13, coeff+14, 0);
1387
0
    _2x2T_h(coeff+4, coeff+7, coeff+ 8, coeff+11, 0);
1388
1389
0
    _2x2T_h (coeff+0, coeff+ 1, coeff+4, coeff+ 5, 1);
1390
0
    _T_odd(coeff+2, coeff+ 3, coeff+6, coeff+ 7);
1391
0
    _T_odd(coeff+8, coeff+12, coeff+9, coeff+13);
1392
0
    _T_odd_odd(coeff+10, coeff+11, coeff+14, coeff+15);
1393
1394
0
    _FwdPermute(coeff);
1395
0
}
1396
1397
static void _InvRotate(int*a, int*b)
1398
0
{
1399
0
    *a -= (*b + 1) >> 1;
1400
0
    *b += (*a + 1) >> 1;
1401
0
    CHECK2(long_word_flag, *a, *b);
1402
0
}
1403
1404
static void _InvScale(int*a, int*b)
1405
0
{
1406
0
    *a += *b;
1407
0
    *b = (*a >> 1) - *b;
1408
0
    CHECK2(long_word_flag, *a, *b);
1409
0
    *a += (*b * 3 + 0) >> 3;
1410
0
    *b -= *a >> 10;
1411
0
    CHECK2(long_word_flag, *a, *b);
1412
0
    *b += *a >> 7;
1413
0
    *b += (*a * 3 + 0) >> 4;
1414
0
    CHECK1(long_word_flag, *b);
1415
0
}
1416
1417
void _jxr_4x4OverlapFilter(int*a, int*b, int*c, int*d,
1418
                           int*e, int*f, int*g, int*h,
1419
                           int*i, int*j, int*k, int*l,
1420
                           int*m, int*n, int*o, int*p)
1421
0
{
1422
0
    _2x2T_h(a, d, m, p, 0);
1423
0
    _2x2T_h(b, c, n, o, 0);
1424
0
    _2x2T_h(e, h, i, l, 0);
1425
0
    _2x2T_h(f, g, j, k, 0);
1426
1427
0
    _InvRotate(n, m);
1428
0
    _InvRotate(j, i);
1429
0
    _InvRotate(h, d);
1430
0
    _InvRotate(g, c);
1431
0
    _InvT_odd_odd_POST(k, l, o, p);
1432
1433
0
    _InvScale(a, p);
1434
0
    _InvScale(b, o);
1435
0
    _InvScale(e, l);
1436
0
    _InvScale(f, k);
1437
1438
0
    _2x2T_h_POST(a, d, m, p);
1439
0
    _2x2T_h_POST(b, c, n, o);
1440
0
    _2x2T_h_POST(e, h, i, l);
1441
0
    _2x2T_h_POST(f, g, j, k);
1442
0
}
1443
1444
void _jxr_4OverlapFilter(int*a, int*b, int*c, int*d)
1445
0
{
1446
0
    *a += *d;
1447
0
    *b += *c;
1448
0
    *d -= ((*a + 1) >> 1);
1449
0
    *c -= ((*b + 1) >> 1);
1450
0
    CHECK4(long_word_flag, *a, *b, *d, *c);
1451
0
    _InvScale(a, d);
1452
0
    _InvScale(b, c);
1453
0
    *a += ((*d * 3 + 4) >> 3);
1454
0
    *b += ((*c * 3 + 4) >> 3);
1455
0
    *d -= (*a >> 1);
1456
0
    *c -= (*b >> 1);
1457
0
    CHECK4(long_word_flag, *a, *b, *d, *c);
1458
0
    *a += *d;
1459
0
    *b += *c;
1460
0
    *d *= -1;
1461
0
    *c *= -1;
1462
0
    CHECK4(long_word_flag, *a, *b, *d, *c);
1463
0
    _InvRotate(c, d);
1464
0
    *d += ((*a + 1) >> 1);
1465
0
    *c += ((*b + 1) >> 1);
1466
0
    *a -= *d;
1467
0
    *b -= *c;
1468
0
    CHECK4(long_word_flag, *a, *b, *d, *c);
1469
0
}
1470
1471
void _jxr_2x2OverlapFilter(int*a, int*b, int*c, int*d)
1472
0
{
1473
0
    *a += *d;
1474
0
    *b += *c;
1475
0
    *d -= (*a + 1) >> 1;
1476
0
    *c -= (*b + 1) >> 1;
1477
0
    CHECK4(long_word_flag, *a, *b, *d, *c);
1478
0
    *b += (*a + 2) >> 2;
1479
0
    *a += (*b + 1) >> 1;
1480
1481
0
    *a += (*b >> 5);
1482
0
    *a += (*b >> 9);
1483
0
    *a += (*b >> 13);
1484
0
    CHECK2(long_word_flag, *a, *b);
1485
1486
0
    *b += (*a + 2) >> 2;
1487
1488
0
    *d += (*a + 1) >> 1;
1489
0
    *c += (*b + 1) >> 1;
1490
0
    *a -= *d;
1491
0
    CHECK4(long_word_flag, *a, *b, *d, *c);
1492
0
    *b -= *c;
1493
0
    CHECK1(long_word_flag, *b);
1494
0
}
1495
1496
void _jxr_2OverlapFilter(int*a, int*b)
1497
0
{
1498
0
    *b += ((*a + 2) >> 2);
1499
0
    *a += ((*b + 1) >> 1);
1500
0
    *a += (*b >> 5);
1501
0
    *a += (*b >> 9);
1502
0
    CHECK2(long_word_flag, *a, *b);
1503
0
    *a += (*b >> 13);
1504
0
    *b += ((*a + 2) >> 2);
1505
0
    CHECK2(long_word_flag, *a, *b);
1506
0
}
1507
1508
/* Prefiltering... */
1509
1510
static void fwdT_Odd_Odd_PRE(int*a, int*b, int*c, int*d)
1511
0
{
1512
0
    int t1;
1513
0
    int t2;
1514
0
    *d += *a;
1515
0
    *c -= *b;
1516
0
    t1 = *d >> 1;
1517
0
    t2 = *c >> 1;
1518
0
    *a -= t1;
1519
0
    *b += t2;
1520
0
    CHECK4(long_word_flag, *d, *c, *a, *b);
1521
0
    *a += (*b * 3 + 4) >> 3;
1522
0
    *b -= (*a * 3 + 2) >> 2;
1523
0
    CHECK2(long_word_flag, *a, *b);
1524
0
    *a += (*b * 3 + 6) >> 3;
1525
0
    *b -= t2;
1526
0
    CHECK2(long_word_flag, *a, *b);
1527
0
    *a += t1;
1528
0
    *c += *b;
1529
0
    *d -= *a;
1530
0
    CHECK3(long_word_flag, *a, *c, *d);
1531
0
}
1532
1533
static void fwdScale(int*a, int*b)
1534
0
{
1535
0
    *b -= (*a * 3 + 0) >> 4;
1536
0
    CHECK1(long_word_flag, *b);
1537
0
    *b -= *a >> 7;
1538
0
    CHECK1(long_word_flag, *b);
1539
0
    *b += *a >> 10;
1540
0
    *a -= (*b * 3 + 0) >> 3;
1541
0
    CHECK2(long_word_flag, *b, *a);
1542
0
    *b = (*a >> 1) - *b;
1543
0
    *a -= *b;
1544
0
    CHECK2(long_word_flag, *b, *a);
1545
0
}
1546
1547
static void fwdRotate(int*a, int*b)
1548
0
{
1549
0
    *b -= (*a + 1) >> 1;
1550
0
    *a += (*b + 1) >> 1;
1551
0
    CHECK2(long_word_flag, *b, *a);
1552
0
}
1553
1554
void _jxr_4x4PreFilter(int*a, int*b, int*c, int*d,
1555
                       int*e, int*f, int*g, int*h,
1556
                       int*i, int*j, int*k, int*l,
1557
                       int*m, int*n, int*o, int*p)
1558
0
{
1559
0
    _2x2T_h_Enc(a, d, m, p);
1560
0
    _2x2T_h_Enc(b, c, n, o);
1561
0
    _2x2T_h_Enc(e, h, i, l);
1562
0
    _2x2T_h_Enc(f, g, j, k);
1563
1564
0
    fwdScale(a, p);
1565
0
    fwdScale(b, o);
1566
0
    fwdScale(e, l);
1567
0
    fwdScale(f, k);
1568
1569
0
    fwdRotate(n, m);
1570
0
    fwdRotate(j, i);
1571
0
    fwdRotate(h, d);
1572
0
    fwdRotate(g, c);
1573
0
    fwdT_Odd_Odd_PRE(k, l, o, p);
1574
1575
0
    _2x2T_h(a, d, m, p, 0);
1576
0
    _2x2T_h(b, c, n, o, 0);
1577
0
    _2x2T_h(e, h, i, l, 0);
1578
0
    _2x2T_h(f, g, j, k, 0);
1579
0
}
1580
1581
void _jxr_4PreFilter(int*a, int*b, int*c, int*d)
1582
0
{
1583
0
    *a += *d;
1584
0
    *b += *c;
1585
0
    *d -= ((*a + 1) >> 1);
1586
0
    *c -= ((*b + 1) >> 1);
1587
0
    CHECK4(long_word_flag, *a, *b, *d, *c);
1588
0
    fwdRotate(c, d);
1589
0
    *d *= -1;
1590
0
    *c *= -1;
1591
0
    *a -= *d;
1592
0
    *b -= *c;
1593
0
    CHECK4(long_word_flag, *d, *c, *a, *b);
1594
0
    *d += (*a >> 1);
1595
0
    *c += (*b >> 1);
1596
0
    *a -= ((*d * 3 + 4) >> 3);
1597
0
    *b -= ((*c * 3 + 4) >> 3);
1598
0
    CHECK4(long_word_flag, *d, *c, *a, *b);
1599
0
    fwdScale(a, d);
1600
0
    fwdScale(b, c);
1601
0
    *d += ((*a + 1) >> 1);
1602
0
    *c += ((*b + 1) >> 1);
1603
0
    *a -= *d;
1604
0
    *b -= *c;
1605
0
    CHECK4(long_word_flag, *d, *c, *a, *b);
1606
0
}
1607
1608
void _jxr_2x2PreFilter(int*a, int*b, int*c, int*d)
1609
0
{
1610
0
    *a += *d;
1611
0
    *b += *c;
1612
0
    *d -= ((*a + 1) >> 1);
1613
0
    *c -= ((*b + 1) >> 1);
1614
0
    CHECK4(long_word_flag, *a, *b, *d, *c);
1615
0
    *b -= ((*a + 2) >> 2);
1616
0
    *a -= (*b >> 5);
1617
0
    CHECK2(long_word_flag, *b, *a);
1618
0
    *a -= (*b >> 9);
1619
0
    CHECK1(long_word_flag, *a);
1620
0
    *a -= (*b >> 13);
1621
0
    CHECK1(long_word_flag, *a);
1622
0
    *a -= ((*b + 1) >> 1);
1623
0
    *b -= ((*a + 2) >> 2);
1624
0
    *d += ((*a + 1) >> 1);
1625
0
    *c += ((*b + 1) >> 1);
1626
0
    CHECK4(long_word_flag, *a, *b, *d, *c);
1627
0
    *a -= *d;
1628
0
    *b -= *c;
1629
0
    CHECK2(long_word_flag, *a, *b);
1630
0
}
1631
1632
void _jxr_2PreFilter(int*a, int*b)
1633
0
{
1634
0
    *b -= ((*a + 2) >> 2);
1635
0
    *a -= (*b >> 13);
1636
0
    CHECK2(long_word_flag, *b, *a);
1637
0
    *a -= (*b >> 9);
1638
0
    CHECK1(long_word_flag, *a);
1639
0
    *a -= (*b >> 5);
1640
0
    CHECK1(long_word_flag, *a);
1641
0
    *a -= ((*b + 1) >> 1);
1642
0
    *b -= ((*a + 2) >> 2);
1643
0
    CHECK2(long_word_flag, *a, *b);
1644
0
}
1645
1646
uint8_t _jxr_read_lwf_test_flag()
1647
0
{
1648
0
    return long_word_flag;
1649
0
}
1650
1651
/*
1652
* $Log: algo.c,v $
1653
* Revision 1.11  2011-12-19 15:39:50  thor
1654
* Bumped to 1.33, updated the readme, cleaned the overlap filter.
1655
*
1656
* Revision 1.10  2011-04-28 08:45:42  thor
1657
* Fixed compiler warnings, ported to gcc 4.4, removed obsolete files.
1658
*
1659
* Revision 1.9  2010-03-31 07:50:58  thor
1660
* Replaced by the latest MS version.
1661
*
1662
*
1663
* Revision 1.58 2009/05/29 12:00:00 microsoft
1664
* Reference Software v1.6 updates.
1665
*
1666
* Revision 1.57 2009/05/29 12:00:00 microsoft
1667
* Reference Software v1.6 updates.
1668
*
1669
* Revision 1.56 2009/04/13 12:00:00 microsoft
1670
* Reference Software v1.5 updates.
1671
*
1672
* Revision 1.55 2008-05-13 13:47:11 thor
1673
* Some experiments with a smarter selection for the quantization size,
1674
* does not yet compile.
1675
*
1676
* Revision 1.54 2008-05-09 19:57:48 thor
1677
* Reformatted for unix LF.
1678
*
1679
* Revision 1.53 2008-04-15 14:28:12 thor
1680
* Start of the repository for the jpegxr reference software.
1681
*
1682
* Revision 1.52 2008/03/20 18:11:50 steve
1683
* Clarify MBLPMode calculations.
1684
*
1685
* Revision 1.51 2008/03/14 00:54:08 steve
1686
* Add second prefilter for YUV422 and YUV420 encode.
1687
*
1688
* Revision 1.50 2008/03/13 22:32:26 steve
1689
* Fix CBP prediction for YUV422, mode==0.
1690
*
1691
* Revision 1.49 2008/03/13 17:49:31 steve
1692
* Fix problem with YUV422 CBP prediction for UV planes
1693
*
1694
* Add support for YUV420 encoding.
1695
*
1696
* Revision 1.48 2008/03/13 00:07:22 steve
1697
* Encode HP of YUV422
1698
*
1699
* Revision 1.47 2008/03/12 21:10:27 steve
1700
* Encode LP of YUV422
1701
*
1702
* Revision 1.46 2008/03/11 22:12:48 steve
1703
* Encode YUV422 through DC.
1704
*
1705
* Revision 1.45 2008/02/26 23:52:44 steve
1706
* Remove ident for MS compilers.
1707
*
1708
* Revision 1.44 2008/02/22 23:01:33 steve
1709
* Compress macroblock HP CBP packets.
1710
*
1711
* Revision 1.43 2008/02/01 22:49:52 steve
1712
* Handle compress of YUV444 color DCONLY
1713
*
1714
* Revision 1.42 2008/01/08 23:23:32 steve
1715
* Minor math error in overlap code.
1716
*
1717
* Revision 1.41 2008/01/08 01:06:20 steve
1718
* Add first pass overlap filtering.
1719
*
1720
* Revision 1.40 2008/01/04 17:07:35 steve
1721
* API interface for setting QP values.
1722
*
1723
* Revision 1.39 2008/01/01 01:08:23 steve
1724
* Compile warning.
1725
*
1726
* Revision 1.38 2008/01/01 01:07:25 steve
1727
* Add missing HP prediction.
1728
*
1729
* Revision 1.37 2007/12/30 00:16:00 steve
1730
* Add encoding of HP values.
1731
*
1732
* Revision 1.36 2007/12/17 23:02:57 steve
1733
* Implement MB_CBP encoding.
1734
*
1735
* Revision 1.35 2007/12/14 17:10:39 steve
1736
* HP CBP Prediction
1737
*
1738
* Revision 1.34 2007/12/12 00:36:46 steve
1739
* Use T_odd instead of InvT_odd for PCT transform.
1740
*
1741
* Revision 1.33 2007/12/06 23:12:40 steve
1742
* Stubs for LP encode operations.
1743
*
1744
* Revision 1.32 2007/11/26 01:47:15 steve
1745
* Add copyright notices per MS request.
1746
*
1747
* Revision 1.31 2007/11/21 23:24:09 steve
1748
* Account for tiles selecting LP_QUANT for pred math.
1749
*
1750
* Revision 1.30 2007/11/16 20:03:57 steve
1751
* Store MB Quant, not qp_index.
1752
*
1753
* Revision 1.29 2007/11/13 03:27:23 steve
1754
* Add Frequency mode LP support.
1755
*
1756
* Revision 1.28 2007/10/30 21:32:46 steve
1757
* Support for multiple tile columns.
1758
*
1759
* Revision 1.27 2007/10/23 00:34:12 steve
1760
* Level1 filtering for YUV422 and YUV420
1761
*
1762
* Revision 1.26 2007/10/22 21:52:37 steve
1763
* Level2 filtering for YUV420
1764
*
1765
* Revision 1.25 2007/10/19 22:07:11 steve
1766
* Prediction of YUV420 chroma planes.
1767
*
1768
* Revision 1.24 2007/10/19 16:20:21 steve
1769
* Parse YUV420 HP
1770
*
1771
* Revision 1.23 2007/10/17 23:43:19 steve
1772
* Add support for YUV420
1773
*
1774
* Revision 1.22 2007/10/04 00:30:47 steve
1775
* Fix prediction of HP CBP for YUV422 data.
1776
*
1777
* Revision 1.21 2007/10/02 20:36:29 steve
1778
* Fix YUV42X DC prediction, add YUV42X HP parsing.
1779
*
1780
* Revision 1.20 2007/10/01 20:39:33 steve
1781
* Add support for YUV422 LP bands.
1782
*
1783
* Revision 1.19 2007/09/20 18:04:10 steve
1784
* support render of YUV422 images.
1785
*
1786
* Revision 1.18 2007/09/13 23:12:34 steve
1787
* Support color HP bands.
1788
*
1789
* Revision 1.17 2007/09/11 00:40:06 steve
1790
* Fix rendering of chroma to add the missing *2.
1791
* Fix handling of the chroma LP samples
1792
* Parse some of the HP CBP data in chroma.
1793
*
1794
* Revision 1.16 2007/09/08 01:01:43 steve
1795
* YUV444 color parses properly.
1796
*
1797
* Revision 1.15 2007/09/04 19:10:46 steve
1798
* Finish level1 overlap filtering.
1799
*
1800
* Revision 1.14 2007/08/31 23:31:49 steve
1801
* Initialize CBP VLC tables at the right time.
1802
*
1803
* Revision 1.13 2007/08/28 21:58:52 steve
1804
* Rewrite filtering to match rewritten 4.7
1805
*
1806
* Revision 1.12 2007/08/14 23:39:56 steve
1807
* Fix UpdateModelMB / Add filtering functions.
1808
*
1809
* Revision 1.11 2007/08/04 00:10:51 steve
1810
* Fix subtle loss of -1 values during DC prediction.
1811
*/
1812