Coverage Report

Created: 2026-04-09 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/jpegxr/r_strip.c
Line
Count
Source
1
2
/*************************************************************************
3
*
4
* This software module was originally contributed by Microsoft
5
* Corporation in the course of development of the
6
* ITU-T T.832 | ISO/IEC 29199-2 ("JPEG XR") format standard for
7
* reference purposes and its performance may not have been optimized.
8
*
9
* This software module is an implementation of one or more
10
* tools as specified by the JPEG XR standard.
11
*
12
* ITU/ISO/IEC give You a royalty-free, worldwide, non-exclusive
13
* copyright license to copy, distribute, and make derivative works
14
* of this software module or modifications thereof for use in
15
* products claiming conformance to the JPEG XR standard as
16
* specified by ITU-T T.832 | ISO/IEC 29199-2.
17
*
18
* ITU/ISO/IEC give users the same free license to this software
19
* module or modifications thereof for research purposes and further
20
* ITU/ISO/IEC standardization.
21
*
22
* Those intending to use this software module in products are advised
23
* that its use may infringe existing patents. ITU/ISO/IEC have no
24
* liability for use of this software module or modifications thereof.
25
*
26
* Copyright is not released for products that do not conform to
27
* to the JPEG XR standard as specified by ITU-T T.832 |
28
* ISO/IEC 29199-2.
29
*
30
******** Section to be removed when the standard is published ************
31
*
32
* Assurance that the contributed software module can be used
33
* (1) in the ITU-T "T.JXR" | ISO/IEC 29199 ("JPEG XR") standard once the
34
* standard has been adopted; and
35
* (2) to develop the JPEG XR standard:
36
*
37
* Microsoft Corporation and any subsequent contributors to the development
38
* of this software grant ITU/ISO/IEC all rights necessary to include
39
* the originally developed software module or modifications thereof in the
40
* JPEG XR standard and to permit ITU/ISO/IEC to offer such a royalty-free,
41
* worldwide, non-exclusive copyright license to copy, distribute, and make
42
* derivative works of this software module or modifications thereof for
43
* use in products claiming conformance to the JPEG XR standard as
44
* specified by ITU-T T.832 | ISO/IEC 29199-2, and to the extent that
45
* such originally developed software module or portions of it are included
46
* in an ITU/ISO/IEC standard. To the extent that the original contributors
47
* may own patent rights that would be required to make, use, or sell the
48
* originally developed software module or portions thereof included in the
49
* ITU/ISO/IEC standard in a conforming product, the contributors will
50
* assure ITU/ISO/IEC that they are willing to negotiate licenses under
51
* reasonable and non-discriminatory terms and conditions with
52
* applicants throughout the world and in accordance with their patent
53
* rights declarations made to ITU/ISO/IEC (if any).
54
*
55
* Microsoft, any subsequent contributors, and ITU/ISO/IEC additionally
56
* gives You a free license to this software module or modifications
57
* thereof for the sole purpose of developing the JPEG XR standard.
58
*
59
******** end of section to be removed when the standard is published *****
60
*
61
* Microsoft Corporation retains full right to modify and use the code
62
* for its own purpose, to assign or donate the code to a third party,
63
* and to inhibit third parties from using the code for products that
64
* do not conform to the JPEG XR standard as specified by ITU-T T.832 |
65
* ISO/IEC 29199-2.
66
*
67
* This copyright notice must be included in all copies or derivative
68
* works.
69
*
70
* Copyright (c) ITU-T/ISO/IEC 2008, 2009.
71
***********************************************************************/
72
73
#ifdef _MSC_VER
74
#pragma comment (user,"$Id: r_strip.c,v 1.18 2011-11-19 20:52:34 thor Exp $")
75
#endif
76
77
# include "jxr_priv.h"
78
# include <limits.h>
79
# include <assert.h>
80
# include <math.h>
81
# include <memory.h>
82
83
static void dclphp_shuffle(int*data, int dclp_count);
84
static void unblock_shuffle444(int*data);
85
static void unblock_shuffle422(int*data);
86
static void unblock_shuffle420(int*data);
87
88
static void dequantize_up_dclp(jxr_image_t image, int use_my, int ch)
89
0
{
90
0
    int tx, ty = 0;
91
0
    int dc_quant = 0;
92
0
    unsigned int strip;
93
0
    unsigned int i;
94
95
0
    int lp_coeff_count = 16;
96
0
    if (ch > 0) {
97
0
        if (image->use_clr_fmt == 2/*YUV422*/)
98
0
            lp_coeff_count = 8;
99
0
        else if (image->use_clr_fmt == 1/*YUV420*/)
100
0
            lp_coeff_count = 4;
101
0
    }
102
103
0
    strip = use_my -1;
104
0
    for(i=0; i < image->tile_rows; i++)
105
0
    {
106
        /* Figure out what ty is */
107
0
        if(strip >= image->tile_row_position[i] && strip <image->tile_row_position[i] + image->tile_row_height[i])
108
0
        {
109
0
            ty = i;
110
0
            break;
111
0
        }
112
0
    }
113
114
    /* The current "cur" is now made up into DC coefficients, so
115
    we no longer need the strip_up levels. Dequantize them,
116
    inverse tranform then and deliver them to output. */
117
0
    for (tx = 0 ; tx < (int) image->tile_columns ; tx += 1) {
118
0
        int mx;
119
0
        if(image->dc_frame_uniform)
120
0
            dc_quant = image->dc_quant_ch[ch];
121
0
        else
122
0
            dc_quant = image->tile_quant[ty *(image->tile_columns) + tx].dc_quant_ch[ch];
123
0
        dc_quant = _jxr_quant_map(image, dc_quant, ch==0? 1 : 0/* iShift for YONLY */);
124
125
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
126
0
            int lp_quant_idx = MACROBLK_UP1_LP_QUANT(image,ch,tx,mx);
127
0
            int k;
128
0
            int lp_quant_use;
129
130
0
            int lp_quant_raw = 0;
131
0
            if(image->lp_frame_uniform)
132
0
                lp_quant_raw = image->lp_quant_ch[ch][lp_quant_idx];
133
0
            else
134
0
                lp_quant_raw = image->tile_quant[ty *(image->tile_columns) + tx].lp_quant_ch[ch][lp_quant_idx];
135
136
0
            lp_quant_use = _jxr_quant_map(image, lp_quant_raw, ch==0? 1 : 0/* iShift for YONLY */);
137
0
            MACROBLK_UP_DC(image,ch,tx,mx) *= dc_quant;
138
0
            CHECK1(image->lwf_test, MACROBLK_CUR_DC(image,ch,tx,mx));
139
140
0
            DEBUG(" Dequantize strip=%d tx=%d MBx=%d ch=%d with lp_quant=%d lp_quant_use=%d\n",
141
0
                use_my-1, tx, mx, ch, lp_quant_raw, lp_quant_use);
142
0
            for (k = 1 ; k < lp_coeff_count ; k += 1)
143
0
            {
144
0
                MACROBLK_UP_LP(image,ch,tx,mx,k-1) *= lp_quant_use;
145
0
                CHECK1(image->lwf_test, MACROBLK_UP_LP(image,ch,tx,mx,k-1));
146
0
            }
147
0
        }
148
0
    }
149
150
#if defined(DETAILED_DEBUG)
151
    for (tx = 0 ; tx < (int) image->tile_columns ; tx += 1) {
152
        int mx;
153
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
154
            int jdx;
155
            DEBUG(" DC/LP (strip=%3d, tx=%d mbx=%4d, ch=%d) Dequant:", use_my-1, tx, mx, ch);
156
            DEBUG(" 0x%08x", MACROBLK_UP_DC(image,ch,tx,mx));
157
            for (jdx = 0; jdx < lp_coeff_count-1 ; jdx += 1) {
158
                DEBUG(" 0x%08x", MACROBLK_UP_LP(image,ch,tx,mx,jdx));
159
                if ((jdx+1)%4 == 3 && jdx != (lp_coeff_count-2))
160
                    DEBUG("\n%*s:", 48, "");
161
            }
162
            DEBUG("\n");
163
        }
164
    }
165
#endif
166
0
}
167
168
169
static void IPCT_level1_up1(jxr_image_t image, int use_my, int ch)
170
0
{
171
0
    int idx;
172
173
0
    dequantize_up_dclp(image, use_my, ch);
174
175
0
    DEBUG(" DC-LP IPCT transforms (first level) for strip %d channel %d\n", use_my-1, ch);
176
177
    /* Reverse transform the DC/LP to 16 DC values. */
178
179
0
    for (idx = 0 ; idx < (int) EXTENDED_WIDTH_BLOCKS(image); idx += 1) {
180
0
        DEBUG(" DC-LP IPCT transforms for mb[%d %d]\n", idx, use_my-1);
181
182
0
        if (ch > 0 && image->use_clr_fmt == 1/*YUV420*/) {
183
184
0
            _jxr_2x2IPCT(image->strip[ch].up1[idx].data+0);
185
0
            _jxr_InvPermute2pt(image->strip[ch].up1[idx].data+1,
186
0
                image->strip[ch].up1[idx].data+2);
187
188
            /* Scale up the chroma channel */
189
0
            if (image->scaled_flag) {
190
0
                int jdx;
191
0
                for (jdx = 0 ; jdx < 4 ; jdx += 1)
192
0
                    image->strip[ch].up1[idx].data[jdx] *= 2;
193
0
            }
194
195
#if defined(DETAILED_DEBUG)
196
            DEBUG(" DC/LP (strip=%3d, mbx=%4d, ch=%d) IPCT:", use_my-1, idx, ch);
197
            DEBUG(" 0x%08x", MACROBLK_UP_DC(image,ch,0,idx));
198
            DEBUG(" 0x%08x", MACROBLK_UP_LP(image,ch,0,idx,0));
199
            DEBUG(" 0x%08x", MACROBLK_UP_LP(image,ch,0,idx,1));
200
            DEBUG(" 0x%08x", MACROBLK_UP_LP(image,ch,0,idx,2));
201
            DEBUG("\n");
202
#endif
203
0
        } else if (ch > 0 && image->use_clr_fmt == 2/*YUV422*/) {
204
#if defined(DETAILED_DEBUG)
205
            int jdx;
206
            DEBUG(" DC/LP scaled_flag=%d\n", image->scaled_flag);
207
            DEBUG(" DC/LP (strip=%3d, mbx=%4d, ch=%d) Pre-IPCT:", use_my-1, idx, ch);
208
            DEBUG(" 0x%08x", MACROBLK_UP_DC(image,ch,0,idx));
209
            for (jdx = 0; jdx < 7 ; jdx += 1) {
210
                DEBUG(" 0x%08x", MACROBLK_UP_LP(image,ch,0,idx,jdx));
211
                if ((jdx+1)%4 == 3 && jdx != 6)
212
                    DEBUG("\n%*s:", 44, "");
213
            }
214
            DEBUG("\n");
215
#endif
216
217
0
            _jxr_2ptT(image->strip[ch].up1[idx].data+0,
218
0
                image->strip[ch].up1[idx].data+4);
219
0
            _jxr_2x2IPCT(image->strip[ch].up1[idx].data+0);
220
0
            _jxr_2x2IPCT(image->strip[ch].up1[idx].data+4);
221
222
0
            _jxr_InvPermute2pt(image->strip[ch].up1[idx].data+1,
223
0
                image->strip[ch].up1[idx].data+2);
224
0
            _jxr_InvPermute2pt(image->strip[ch].up1[idx].data+5,
225
0
                image->strip[ch].up1[idx].data+6);
226
227
#if defined(DETAILED_DEBUG)
228
            DEBUG(" DC/LP scaled_flag=%d\n", image->scaled_flag);
229
            DEBUG(" DC/LP (strip=%3d, mbx=%4d, ch=%d) scaled:", use_my-1, idx, ch);
230
            DEBUG(" 0x%08x", MACROBLK_UP_DC(image,ch,0,idx));
231
            for (jdx = 0; jdx < 7 ; jdx += 1) {
232
                DEBUG(" 0x%08x", MACROBLK_UP_LP(image,ch,0,idx,jdx));
233
                if ((jdx+1)%4 == 3 && jdx != 6)
234
                    DEBUG("\n%*s:", 42, "");
235
            }
236
            DEBUG("\n");
237
#endif
238
            /* Scale up the chroma channel */
239
0
            if (image->scaled_flag) {
240
0
                int jdx;
241
0
                for (jdx = 0 ; jdx < 8 ; jdx += 1)
242
0
                    image->strip[ch].up1[idx].data[jdx] *= 2;
243
0
            }
244
245
#if defined(DETAILED_DEBUG)
246
            DEBUG(" DC/LP scaled_flag=%d\n", image->scaled_flag);
247
            DEBUG(" DC/LP (strip=%3d, mbx=%4d, ch=%d) IPCT:", use_my-1, idx, ch);
248
            DEBUG(" 0x%08x", MACROBLK_UP_DC(image,ch,0,idx));
249
            for (jdx = 0; jdx < 7 ; jdx += 1) {
250
                DEBUG(" 0x%08x", MACROBLK_UP_LP(image,ch,0,idx,jdx));
251
                if ((jdx+1)%4 == 3 && jdx != 6)
252
                    DEBUG("\n%*s:", 40, "");
253
            }
254
            DEBUG("\n");
255
#endif
256
0
        } else {
257
258
            /* Channel 0 of everything, and Channel-N of full
259
            resolution colors, are processed here. */
260
0
            _jxr_4x4IPCT(image->strip[ch].up1[idx].data);
261
262
            /* Scale up the chroma channel */
263
0
            if (ch > 0 && image->scaled_flag) {
264
0
                int jdx;
265
0
                for (jdx = 0 ; jdx < 16 ; jdx += 1)
266
0
                    image->strip[ch].up1[idx].data[jdx] *= 2;
267
0
            }
268
269
#if defined(DETAILED_DEBUG)
270
            int jdx;
271
            DEBUG(" DC/LP (strip=%3d, mbx=%4d, ch=%d) IPCT:", use_my-1, idx, ch);
272
            DEBUG(" 0x%08x", MACROBLK_UP_DC(image,ch,0,idx));
273
            for (jdx = 0; jdx < 15 ; jdx += 1) {
274
                DEBUG(" 0x%08x", MACROBLK_UP_LP(image,ch,0,idx,jdx));
275
                if ((jdx+1)%4 == 3 && jdx != 14)
276
                    DEBUG("\n%*s:", 40, "");
277
            }
278
            DEBUG("\n");
279
#endif
280
0
        }
281
282
0
    }
283
284
0
}
285
286
static void IPCT_level2_up2(jxr_image_t image, int use_my, int ch)
287
0
{
288
0
    int idx;
289
290
0
    for (idx = 0 ; idx < (int) EXTENDED_WIDTH_BLOCKS(image); idx += 1) {
291
0
        int jdx;
292
        /* Reshuffle the DCLP with the HP data to get
293
        DC-LP stretches in the data stream. */
294
0
        int dclp_count = 16;
295
0
        int hp_quant_raw;
296
0
        int hp_quant;
297
298
0
        if (ch>0 && image->use_clr_fmt == 2/*YUV422*/)
299
0
            dclp_count = 8;
300
0
        else if (ch>0 && image->use_clr_fmt == 1/*YUV420*/)
301
0
            dclp_count = 4;
302
303
0
        dclphp_shuffle(image->strip[ch].up2[idx].data, dclp_count);
304
305
0
        DEBUG(" DC-LP-HP IPCT transforms for (second level) strip %d MBx=%d ch=%d\n",
306
0
            use_my-2, idx, ch);
307
308
0
        hp_quant_raw = MACROBLK_UP2_HP_QUANT(image,ch,0,idx);
309
0
        hp_quant = _jxr_quant_map(image, hp_quant_raw, 1);
310
311
        /* IPCT transform to absorb HP band data. */
312
0
        for (jdx = 0 ; jdx < 16*dclp_count ; jdx += 16) {
313
0
            int k;
314
#if defined(DETAILED_DEBUG)
315
            {
316
                int pix;
317
                DEBUG(" DC-LP-HP (strip=%3d, mbx=%4d ch=%d, block=%2d) pre-IPCT:",
318
                    use_my-2, idx, ch, jdx/16);
319
                for (pix = 0; pix < 16 ; pix += 1) {
320
                    DEBUG(" 0x%08x", image->strip[ch].up2[idx].data[jdx+pix]);
321
                    if (pix%4 == 3 && pix != 15)
322
                        DEBUG("\n%*s:", 56, "");
323
                }
324
                DEBUG("\n");
325
            }
326
#endif
327
0
            DEBUG(" Dequantize strip=%d MBx=%d ch=%d block=%d with hp_quant=%d (raw=%d)\n",
328
0
                use_my-2, idx, ch, jdx/16, hp_quant, hp_quant_raw);
329
0
            for (k = 1 ; k < 16 ; k += 1)
330
0
            {
331
0
                image->strip[ch].up2[idx].data[jdx+k] *= hp_quant;
332
0
                CHECK1(image->lwf_test, image->strip[ch].up2[idx].data[jdx+k]);
333
0
            }
334
335
0
            _jxr_4x4IPCT(image->strip[ch].up2[idx].data+jdx);
336
#if defined(DETAILED_DEBUG)
337
            {
338
                int pix;
339
                DEBUG(" DC-LP-HP (strip=%3d, mbx=%4d ch=%d block=%2d) IPCT:",
340
                    use_my-2, idx, ch, jdx/16);
341
                for (pix = 0; pix < 16 ; pix += 1) {
342
                    DEBUG(" 0x%08x", image->strip[ch].up2[idx].data[jdx+pix]);
343
                    if (pix%4 == 3 && pix != 15)
344
                        DEBUG("\n%*s:", 51, "");
345
                }
346
                DEBUG("\n");
347
            }
348
#endif
349
0
        }
350
351
0
    }
352
0
}
353
354
0
#define TOP_Y(y) ( y == image->tile_row_position[ty])
355
0
#define BOTTOM_Y(y) ( y == image->tile_row_position[ty] + image->tile_row_height[ty] - 1)
356
0
#define LEFT_X(idx) ( idx == 0)
357
0
#define RIGHT_X(idx) ( idx == image->tile_column_width[tx] -1 )
358
359
360
static void overlap_level1_up2_444(jxr_image_t image, int use_my, int ch)
361
0
{
362
0
    int tx = 0; /* XXXX */
363
0
    int top_my = use_my - 2;
364
0
    int idx;
365
366
0
    int ty = 0;
367
    /* 16 Coeffs per MB */
368
0
    assert(ch == 0 || (image->use_clr_fmt != 2/*YUV422*/ && image->use_clr_fmt !=1/* YUV420*/));
369
0
    assert(use_my >= 2);
370
    /* Figure out which tile row the current strip of macroblocks belongs to. */
371
0
    while(top_my > image->tile_row_position[ty]+image->tile_row_height[ty] - 1)
372
0
        ty++;
373
374
0
    for(tx = 0; tx < image->tile_columns; tx++)
375
0
    {
376
        /* Top edge */
377
0
        if(top_my == 0 || (image->disableTileOverlapFlag && TOP_Y(top_my) ))
378
0
        {
379
            /* If this is the very first strip of blocks, then process the
380
            first two scan lines with the smaller 4Overlap filter. */
381
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
382
0
            {
383
                /* Top edge across */
384
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag) || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
385
0
                    int*tp0 = MACROBLK_UP2(image,ch,tx,idx+0).data;
386
0
                    int*tp1 = MACROBLK_UP2(image,ch,tx,idx-1).data; /* Macroblock to the right */
387
388
0
                    _jxr_4OverlapFilter(tp1+2, tp1+3, tp0+0, tp0+1);
389
0
                    _jxr_4OverlapFilter(tp1+6, tp1+7, tp0+4, tp0+5);
390
0
                }
391
0
            }
392
            /* Top left corner */
393
0
            if(tx == 0 || image->disableTileOverlapFlag)
394
0
            {
395
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
396
0
                _jxr_4OverlapFilter(tp0+0, tp0+1, tp0+4, tp0+5);
397
0
            }
398
            /* Top right corner */
399
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
400
0
            {
401
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
402
0
                _jxr_4OverlapFilter(tp0+2, tp0+3, tp0+6, tp0+7);
403
0
            }
404
0
        }
405
406
        /* Bottom edge */
407
0
        if ((top_my+1) == (int) EXTENDED_HEIGHT_BLOCKS(image) || (image->disableTileOverlapFlag && BOTTOM_Y(top_my))) {
408
409
            /* This is the last row, so there is no UP below
410
            TOP. finish up with 4Overlap filters. */
411
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
412
0
            {
413
                /* Bottom edge across */
414
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag)
415
0
                    || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
416
417
0
                        int*tp0 = MACROBLK_UP2(image,ch,tx,idx+0).data;
418
0
                        int*tp1 = MACROBLK_UP2(image,ch,tx,idx-1).data;
419
0
                        _jxr_4OverlapFilter(tp1+10, tp1+11, tp0+8, tp0+9);
420
0
                        _jxr_4OverlapFilter(tp1+14, tp1+15, tp0+12, tp0+13);
421
0
                }
422
0
            }
423
424
            /* Bottom left corner */
425
0
            if(tx == 0 || image->disableTileOverlapFlag)
426
0
            {
427
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
428
0
                _jxr_4OverlapFilter(tp0+8, tp0+9, tp0+12, tp0+13);
429
0
            }
430
            /* Bottom right corner */
431
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
432
0
            {
433
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
434
0
                _jxr_4OverlapFilter(tp0+10, tp0+11, tp0+14, tp0+15);
435
0
            }
436
0
        }
437
438
0
        for (idx = 0 ; idx < image->tile_column_width[tx] ; idx += 1) {
439
0
            if ((top_my+1) < (int) EXTENDED_HEIGHT_BLOCKS(image)) {
440
441
0
                if ((tx == 0 && idx==0 && !image->disableTileOverlapFlag) ||
442
0
                    (image->disableTileOverlapFlag && LEFT_X(idx) && !BOTTOM_Y(top_my))) {
443
0
                        int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
444
0
                        int*up0 = MACROBLK_UP1(image,ch,tx,0).data;
445
446
                        /* Left edge Across Vertical MBs */
447
0
                        _jxr_4OverlapFilter(tp0+8, tp0+12, up0+0, up0+4);
448
0
                        _jxr_4OverlapFilter(tp0+9, tp0+13, up0+1, up0+5);
449
0
                }
450
451
0
                if (((image->tile_column_position[tx] + idx < EXTENDED_WIDTH_BLOCKS(image)-1) && !image->disableTileOverlapFlag ) ||
452
0
                    ( image->disableTileOverlapFlag && !RIGHT_X(idx) && !BOTTOM_Y(top_my) )
453
0
                    ) {
454
                        /* This assumes that the DCLP coefficients are the first
455
                        16 values in the array, and ordered properly. */
456
0
                        int*tp0 = MACROBLK_UP2(image,ch,tx,idx+0).data;
457
0
                        int*tp1 = MACROBLK_UP2(image,ch,tx,idx+1).data;
458
0
                        int*up0 = MACROBLK_UP1(image,ch,tx,idx+0).data;
459
0
                        int*up1 = MACROBLK_UP1(image,ch,tx,idx+1).data;
460
461
                        /* MB below, right, right-below */
462
0
                        _jxr_4x4OverlapFilter(tp0+10, tp0+11, tp1+ 8, tp1+ 9,
463
0
                            tp0+14, tp0+15, tp1+12, tp1+13,
464
0
                            up0+ 2, up0+ 3, up1+ 0, up1+ 1,
465
0
                            up0+ 6, up0+ 7, up1+ 4, up1+ 5);
466
0
                }
467
0
                if((image->tile_column_position[tx] + idx == (int) EXTENDED_WIDTH_BLOCKS(image)-1 && !image->disableTileOverlapFlag) ||
468
0
                    (image->disableTileOverlapFlag && RIGHT_X(idx) && !BOTTOM_Y(top_my)))
469
0
                {
470
0
                    int*tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
471
0
                    int*up0 = MACROBLK_UP1(image,ch,tx,image->tile_column_width[tx]-1).data;
472
473
                    /* Right edge Across Vertical MBs */
474
0
                    _jxr_4OverlapFilter(tp0+10, tp0+14, up0+2, up0+6);
475
0
                    _jxr_4OverlapFilter(tp0+11, tp0+15, up0+3, up0+7);
476
0
                }
477
0
            }
478
0
        }
479
0
    }
480
0
}
481
482
/*
483
*/
484
485
static void overlap_level1_up2_422(jxr_image_t image, int use_my, int ch)
486
0
{
487
0
    int tx = 0; /* XXXX */
488
0
    int top_my = use_my - 2;
489
0
    int idx;
490
491
0
    int ty = 0;
492
0
    assert(ch > 0 && image->use_clr_fmt == 2/*YUV422*/);
493
0
    assert(use_my >= 2);
494
    /* Figure out which tile row the current strip of macroblocks belongs to. */
495
0
    while(top_my > image->tile_row_position[ty]+image->tile_row_height[ty] - 1)
496
0
        ty++;
497
498
499
    /* Top edge */
500
0
    if(top_my == 0 || (image->disableTileOverlapFlag && TOP_Y(top_my)))
501
0
    {
502
0
        for(tx = 0; tx < image->tile_columns; tx++)
503
0
        {
504
            /* Top Left Corner Difference */
505
0
            if(tx == 0 || image->disableTileOverlapFlag)
506
0
            {
507
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
508
0
                tp0[0] = tp0[0] -tp0[1];
509
0
                CHECK1(image->lwf_test, tp0[0]);
510
0
            }
511
            /* Top Right Corner Difference */
512
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
513
0
            {
514
0
                int *tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
515
0
                tp0[1] = tp0[1] - tp0[0];
516
0
                CHECK1(image->lwf_test, tp0[1]);
517
0
            }
518
0
        }
519
0
    }
520
521
522
    /* Bottom edge */
523
0
    if ((top_my+1) == (int) EXTENDED_HEIGHT_BLOCKS(image) || (image->disableTileOverlapFlag && BOTTOM_Y(top_my)))
524
0
    {
525
0
        for(tx = 0; tx < image->tile_columns; tx++)
526
0
        {
527
            /* Bottom Left Corner Difference */
528
0
            if(tx == 0 || image->disableTileOverlapFlag)
529
0
            {
530
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
531
0
                tp0[6] = tp0[6] -tp0[7];
532
0
                CHECK1(image->lwf_test, tp0[6]);
533
0
            }
534
            /* Bottom Right Corner Difference */
535
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
536
0
            {
537
0
                int *tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
538
0
                tp0[7] = tp0[7] - tp0[6];
539
0
                CHECK1(image->lwf_test, tp0[7]);
540
0
            }
541
0
        }
542
0
    }
543
544
0
    for(tx = 0; tx < image->tile_columns; tx++)
545
0
    {
546
        /* Left edge */
547
0
        if (tx == 0 || image->disableTileOverlapFlag)
548
0
        {
549
            /* Interior left edge */
550
0
            int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
551
0
            _jxr_2OverlapFilter(tp0+2, tp0+4);
552
0
        }
553
554
        /* Right edge */
555
0
        if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
556
0
        {
557
0
            int*tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
558
            /* Interior Right edge */
559
0
            _jxr_2OverlapFilter(tp0+3, tp0+5);
560
0
        }
561
562
563
        /* Top edge */
564
0
        if(top_my == 0 || (image->disableTileOverlapFlag && TOP_Y(top_my) ))
565
0
        {
566
            /* If this is the very first strip of blocks, then process the
567
            first two scan lines with the smaller 4Overlap filter. */
568
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
569
0
            {
570
                /* Top edge across */
571
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag) || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
572
0
                    int*tp0 = MACROBLK_UP2(image,ch,tx,idx+0).data;
573
0
                    int*tp1 = MACROBLK_UP2(image,ch,tx,idx-1).data; /* The macroblock to the right */
574
575
0
                    _jxr_2OverlapFilter(tp1+1, tp0+0);
576
0
                }
577
0
            }
578
0
        }
579
580
        /* Bottom edge */
581
0
        if ((top_my+1) == (int) EXTENDED_HEIGHT_BLOCKS(image) || (image->disableTileOverlapFlag && BOTTOM_Y(top_my))) {
582
583
            /* This is the last row, so there is no UP below
584
            TOP. finish up with 4Overlap filters. */
585
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
586
0
            {
587
                /* Bottom edge across */
588
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag)
589
0
                    || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
590
0
                        int*tp0 = MACROBLK_UP2(image,ch,tx,idx+0).data;
591
0
                        int*tp1 = MACROBLK_UP2(image,ch,tx,idx - 1).data;
592
0
                        _jxr_2OverlapFilter(tp1+7, tp0+6);
593
0
                }
594
0
            }
595
0
        }
596
597
0
        for (idx = 0 ; idx < image->tile_column_width[tx] ; idx += 1) {
598
0
            if(top_my< EXTENDED_HEIGHT_BLOCKS(image) -1)
599
0
            {
600
0
                if ((tx == 0 && idx==0 && !image->disableTileOverlapFlag) ||
601
0
                    (image->disableTileOverlapFlag && LEFT_X(idx) && !BOTTOM_Y(top_my))) {
602
                        /* Across vertical blocks, left edge */
603
0
                        int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
604
0
                        int*up0 = MACROBLK_UP1(image,ch,tx,0).data;
605
606
                        /* Left edge across vertical MBs */
607
0
                        _jxr_2OverlapFilter(tp0+6, up0+0);
608
0
                }
609
610
0
                if((image->tile_column_position[tx] + idx == (int) EXTENDED_WIDTH_BLOCKS(image)-1 && !image->disableTileOverlapFlag) ||
611
0
                    (image->disableTileOverlapFlag && RIGHT_X(idx) && !BOTTOM_Y(top_my)))
612
0
                {
613
0
                    int*tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
614
0
                    int*up0 = MACROBLK_UP1(image,ch,tx,image->tile_column_width[tx]-1).data;
615
616
                    /* Right edge across MBs */
617
0
                    _jxr_2OverlapFilter(tp0+7, up0+1);
618
0
                }
619
620
0
                if (((image->tile_column_position[tx] + idx < EXTENDED_WIDTH_BLOCKS(image)-1) && !image->disableTileOverlapFlag ) ||
621
0
                    ( image->disableTileOverlapFlag && !RIGHT_X(idx) && !BOTTOM_Y(top_my) )
622
0
                    )
623
0
                {
624
                    /* This assumes that the DCLP coefficients are the first
625
                    16 values in the array, and ordered properly. */
626
0
                    int*tp0 = MACROBLK_UP2(image,ch,tx,idx+0).data;
627
0
                    int*tp1 = MACROBLK_UP2(image,ch,tx,idx+1).data;
628
0
                    int*up0 = MACROBLK_UP1(image,ch,tx,idx+0).data;
629
0
                    int*up1 = MACROBLK_UP1(image,ch,tx,idx+1).data;
630
631
                    /* MB below, right, right-below */
632
0
                    _jxr_2x2OverlapFilter(tp0+7, tp1+6, up0+1, up1+0);
633
0
                }
634
0
            }
635
636
0
            if (((image->tile_column_position[tx] + idx < EXTENDED_WIDTH_BLOCKS(image)-1) && !image->disableTileOverlapFlag ) ||
637
0
                ( image->disableTileOverlapFlag && !RIGHT_X(idx) )
638
0
                )
639
0
            {
640
                /* This assumes that the DCLP coefficients are the first
641
                16 values in the array, and ordered properly. */
642
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,idx+0).data;
643
0
                int*tp1 = MACROBLK_UP2(image,ch,tx,idx+1).data;
644
645
                /* MB to the right */
646
0
                _jxr_2x2OverlapFilter(tp0+3, tp1+2, tp0+5, tp1+4);
647
0
            }
648
0
        }
649
0
    }
650
651
    /* Top edge */
652
0
    if(top_my == 0 || (image->disableTileOverlapFlag && TOP_Y(top_my)))
653
0
    {
654
0
        for(tx = 0; tx < image->tile_columns; tx++)
655
0
        {
656
            /* Top Left Corner Addition */
657
0
            if(tx == 0 || image->disableTileOverlapFlag)
658
0
            {
659
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
660
0
                tp0[0] = tp0[0] + tp0[1];
661
0
                CHECK1(image->lwf_test, tp0[0]);
662
0
            }
663
            /* Top Right Corner Addition */
664
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
665
0
            {
666
0
                int *tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
667
0
                tp0[1] = tp0[1] + tp0[0];
668
0
                CHECK1(image->lwf_test, tp0[1]);
669
0
            }
670
0
        }
671
0
    }
672
673
    /* Bottom edge */
674
0
    if ((top_my+1) == (int) EXTENDED_HEIGHT_BLOCKS(image) || (image->disableTileOverlapFlag && BOTTOM_Y(top_my)))
675
0
    {
676
0
        for(tx = 0; tx < image->tile_columns; tx++)
677
0
        {
678
            /* Bottom Left Corner Addition */
679
0
            if(tx == 0 || image->disableTileOverlapFlag)
680
0
            {
681
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
682
0
                tp0[6] = tp0[6] + tp0[7];
683
0
                CHECK1(image->lwf_test, tp0[6]);
684
0
            }
685
            /* Bottom Right Corner Addition */
686
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
687
0
            {
688
0
                int *tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
689
0
                tp0[7] = tp0[7] + tp0[6];
690
0
                CHECK1(image->lwf_test, tp0[7]);
691
0
            }
692
0
        }
693
0
    }
694
0
}
695
696
static void overlap_level1_up2_420(jxr_image_t image, int use_my, int ch)
697
0
{
698
0
    int tx = 0; /* XXXX */
699
0
    int top_my = use_my - 2;
700
701
0
    int idx;
702
0
    int ty = 0;
703
    /* 4 coeffs*/
704
0
    assert(ch > 0 && image->use_clr_fmt == 1/*YUV420*/);
705
0
    assert(use_my >= 2);
706
    /* Figure out which tile row the current strip of macroblocks belongs to. */
707
0
    while(top_my > image->tile_row_position[ty]+image->tile_row_height[ty] - 1)
708
0
        ty++;
709
710
0
    if(top_my == 0 || (image->disableTileOverlapFlag && TOP_Y(top_my)))
711
0
    {
712
0
        for(tx = 0; tx < image->tile_columns; tx++)
713
0
        {
714
            /* Top Left Corner Difference*/
715
0
            if(tx == 0 || image->disableTileOverlapFlag)
716
0
            {
717
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
718
0
                tp0[0] = tp0[0] -tp0[1];
719
0
                CHECK1(image->lwf_test, tp0[0]);
720
0
            }
721
            /* Top Right Corner Difference*/
722
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
723
0
            {
724
0
                int *tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
725
0
                tp0[1] = tp0[1] - tp0[0];
726
0
                CHECK1(image->lwf_test, tp0[1]);
727
0
            }
728
0
        }
729
0
    }
730
731
    /* Bottom edge */
732
0
    if ((top_my+1) == (int) EXTENDED_HEIGHT_BLOCKS(image) || (image->disableTileOverlapFlag && BOTTOM_Y(top_my)))
733
0
    {
734
0
        for(tx = 0; tx < image->tile_columns; tx++)
735
0
        {
736
            /* Bottom Left Corner Difference*/
737
0
            if(tx == 0 || image->disableTileOverlapFlag)
738
0
            {
739
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
740
0
                tp0[2] = tp0[2] -tp0[3];
741
0
                CHECK1(image->lwf_test, tp0[2]);
742
0
            }
743
            /* Bottom Right Corner Difference*/
744
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
745
0
            {
746
0
                int *tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
747
0
                tp0[3] = tp0[3] - tp0[2];
748
0
                CHECK1(image->lwf_test, tp0[3]);
749
0
            }
750
0
        }
751
0
    }
752
753
0
    for(tx = 0; tx < image->tile_columns; tx++)
754
0
    {
755
        /* Top edge */
756
0
        if(top_my == 0 || (image->disableTileOverlapFlag && TOP_Y(top_my)))
757
0
        {
758
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
759
0
            {
760
                /* Top edge across */
761
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag) || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
762
0
                    int*tp0 = MACROBLK_UP2(image,ch,tx,idx+0).data;
763
0
                    int*tp1 = MACROBLK_UP2(image,ch,tx,idx-1).data;
764
0
                    _jxr_2OverlapFilter(tp1+1, tp0+0);
765
0
                }
766
0
            }
767
0
        }
768
769
        /* Bottom edge */
770
0
        if ((top_my+1) == (int) EXTENDED_HEIGHT_BLOCKS(image) || (image->disableTileOverlapFlag && BOTTOM_Y(top_my))) {
771
772
            /* This is the last row, so there is no UP below
773
            TOP. finish up with 4Overlap filters. */
774
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
775
0
            {
776
                /* Bottom edge across */
777
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag)
778
0
                    || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
779
0
                        int*tp0 = MACROBLK_UP2(image,ch,tx,idx+0).data;
780
0
                        int*tp1 = MACROBLK_UP2(image,ch,tx,idx-1).data;
781
0
                        _jxr_2OverlapFilter(tp1+3, tp0+2);
782
0
                }
783
0
            }
784
0
        }
785
0
        else
786
0
        {
787
0
            for (idx = 0 ; idx < image->tile_column_width[tx] ; idx += 1) {
788
789
0
                if ((tx == 0 && idx==0 && !image->disableTileOverlapFlag) ||
790
0
                    (image->disableTileOverlapFlag && LEFT_X(idx) && !BOTTOM_Y(top_my))) {
791
                        /* Left edge across vertical MBs */
792
0
                        int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
793
0
                        int*up0 = MACROBLK_UP1(image,ch,tx,0).data;
794
795
0
                        _jxr_2OverlapFilter(tp0+2, up0+0);
796
0
                }
797
798
0
                if((image->tile_column_position[tx] + idx == (int) EXTENDED_WIDTH_BLOCKS(image)-1 && !image->disableTileOverlapFlag) ||
799
0
                    (image->disableTileOverlapFlag && RIGHT_X(idx) && !BOTTOM_Y(top_my)))
800
0
                {
801
                    /* Right edge across vertical MBs */
802
0
                    int*tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
803
0
                    int*up0 = MACROBLK_UP1(image,ch,tx,image->tile_column_width[tx]-1).data;
804
805
0
                    _jxr_2OverlapFilter(tp0+3, up0+1);
806
0
                }
807
808
0
                if (((image->tile_column_position[tx] + idx < EXTENDED_WIDTH_BLOCKS(image)-1) && !image->disableTileOverlapFlag ) ||
809
0
                    ( image->disableTileOverlapFlag && !RIGHT_X(idx) && !BOTTOM_Y(top_my) )
810
0
                    )
811
0
                {
812
                    /* This assumes that the DCLP coefficients are the first
813
                    16 values in the array, and ordered properly. */
814
                    /* MB below, right, right-below */
815
0
                    int*tp0 = MACROBLK_UP2(image,ch,tx,idx+0).data;
816
0
                    int*tp1 = MACROBLK_UP2(image,ch,tx,idx+1).data;
817
0
                    int*up0 = MACROBLK_UP1(image,ch,tx,idx+0).data;
818
0
                    int*up1 = MACROBLK_UP1(image,ch,tx,idx+1).data;
819
820
0
                    _jxr_2x2OverlapFilter(tp0+3, tp1+2,
821
0
                        up0+1, up1+0);
822
0
                }
823
0
            }
824
0
        }
825
0
    }
826
827
    /* Top edge */
828
0
    if(top_my == 0 || (image->disableTileOverlapFlag && TOP_Y(top_my)))
829
0
    {
830
0
        for(tx = 0; tx < image->tile_columns; tx++)
831
0
        {
832
            /* Top Left Corner Addition */
833
0
            if(tx == 0 || image->disableTileOverlapFlag)
834
0
            {
835
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
836
0
                tp0[0] = tp0[0] + tp0[1];
837
0
                CHECK1(image->lwf_test, tp0[0]);
838
0
            }
839
            /* Top Right Corner Addition */
840
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
841
0
            {
842
0
                int *tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
843
0
                tp0[1] = tp0[1] + tp0[0];
844
0
                CHECK1(image->lwf_test, tp0[1]);
845
0
            }
846
0
        }
847
0
    }
848
849
850
    /* Bottom edge */
851
0
    if ((top_my+1) == (int) EXTENDED_HEIGHT_BLOCKS(image) || (image->disableTileOverlapFlag && BOTTOM_Y(top_my)))
852
0
    {
853
0
        for(tx = 0; tx < image->tile_columns; tx++)
854
0
        {
855
            /* Bottom Left Corner Addition*/
856
0
            if(tx == 0 || image->disableTileOverlapFlag)
857
0
            {
858
0
                int*tp0 = MACROBLK_UP2(image,ch,tx,0).data;
859
0
                tp0[2] = tp0[2] + tp0[3];
860
0
                CHECK1(image->lwf_test, tp0[2]);
861
0
            }
862
            /* Bottom Right Corner Addition*/
863
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
864
0
            {
865
0
                int *tp0 = MACROBLK_UP2(image,ch,tx,image->tile_column_width[tx]-1).data;
866
0
                tp0[3] = tp0[3] + tp0[2];
867
0
                CHECK1(image->lwf_test, tp0[3]);
868
0
            }
869
0
        }
870
0
    }
871
0
}
872
873
874
static void overlap_level1_up2(jxr_image_t image, int use_my, int ch)
875
0
{
876
0
    if (ch == 0) {
877
0
        overlap_level1_up2_444(image, use_my, ch);
878
879
0
    }
880
0
    else {
881
0
        switch (image->use_clr_fmt) {
882
0
            case 1: /*YUV420*/
883
0
                overlap_level1_up2_420(image, use_my, ch);
884
0
                break;
885
0
            case 2: /*YUV422*/
886
0
                overlap_level1_up2_422(image, use_my, ch);
887
0
                break;
888
0
            default:
889
0
                overlap_level1_up2_444(image, use_my, ch);
890
0
                break;
891
0
        }
892
0
    }
893
0
}
894
895
static int*R2B(int*data, int x, int y)
896
0
{
897
0
    int bx = x/4;
898
0
    int by = y/4;
899
0
    int bl = by*4 + bx;
900
0
    return data + bl*16 + 4*(y%4) + x%4;
901
0
}
902
903
static int*R2B42(int*data, int x, int y)
904
0
{
905
0
    int bx = x/4;
906
0
    int by = y/4;
907
0
    int bl = by*2 + bx;
908
0
    return data + bl*16 + 4*(y%4) + x%4;
909
0
}
910
911
static void overlap_level2_up3_444(jxr_image_t image, int use_my, int ch)
912
0
{
913
0
    int tx = 0; /* XXXX */
914
0
    int top_my = use_my - 3;
915
0
    int idx;
916
0
    int ty = 0;
917
918
0
    assert(ch == 0 || (image->use_clr_fmt != 2/*YUV422*/ && image->use_clr_fmt !=1/* YUV420*/));
919
0
    assert(use_my >= 3);
920
0
    DEBUG("Overlap Level2 for row %d\n", top_my);
921
922
    /* Figure out which tile row the current strip of macroblocks belongs to. */
923
0
    while(top_my > image->tile_row_position[ty]+image->tile_row_height[ty] - 1)
924
0
        ty++;
925
926
0
    for(tx = 0; tx < image->tile_columns; tx++)
927
0
    {
928
0
        int jdx;
929
        /* Left edge */
930
0
        if (tx == 0 || image->disableTileOverlapFlag)
931
0
        {
932
0
            int*dp = MACROBLK_UP3(image,ch,tx,0).data;
933
0
            for (jdx = 2 ; jdx < 14 ; jdx += 4) {
934
0
                _jxr_4OverlapFilter(R2B(dp,0,jdx+0),R2B(dp,0,jdx+1),R2B(dp,0,jdx+2),R2B(dp,0,jdx+3));
935
0
                _jxr_4OverlapFilter(R2B(dp,1,jdx+0),R2B(dp,1,jdx+1),R2B(dp,1,jdx+2),R2B(dp,1,jdx+3));
936
0
            }
937
0
        }
938
939
        /* Right edge */
940
0
        if(tx == image->tile_columns -1 || image->disableTileOverlapFlag){
941
0
            int*dp = MACROBLK_UP3(image,ch,tx,image->tile_column_width[tx]-1).data;
942
0
            for (jdx = 2 ; jdx < 14 ; jdx += 4) {
943
0
                _jxr_4OverlapFilter(R2B(dp,14,jdx+0),R2B(dp,14,jdx+1),R2B(dp,14,jdx+2),R2B(dp,14,jdx+3));
944
0
                _jxr_4OverlapFilter(R2B(dp,15,jdx+0),R2B(dp,15,jdx+1),R2B(dp,15,jdx+2),R2B(dp,15,jdx+3));
945
0
            }
946
0
        }
947
948
        /* Top edge */
949
0
        if(top_my == 0 || (image->disableTileOverlapFlag && TOP_Y(top_my) ))
950
0
        {
951
            /* If this is the very first strip of blocks, then process the
952
            first two scan lines with the smaller 4Overlap filter. */
953
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
954
0
            {
955
0
                int*dp = MACROBLK_UP3(image,ch,tx,idx).data;
956
0
                _jxr_4OverlapFilter(R2B(dp, 2,0),R2B(dp, 3,0),R2B(dp, 4,0),R2B(dp, 5,0));
957
0
                _jxr_4OverlapFilter(R2B(dp, 6,0),R2B(dp, 7,0),R2B(dp, 8,0),R2B(dp, 9,0));
958
0
                _jxr_4OverlapFilter(R2B(dp,10,0),R2B(dp,11,0),R2B(dp,12,0),R2B(dp,13,0));
959
960
0
                _jxr_4OverlapFilter(R2B(dp, 2,1),R2B(dp, 3,1),R2B(dp, 4,1),R2B(dp, 5,1));
961
0
                _jxr_4OverlapFilter(R2B(dp, 6,1),R2B(dp, 7,1),R2B(dp, 8,1),R2B(dp, 9,1));
962
0
                _jxr_4OverlapFilter(R2B(dp,10,1),R2B(dp,11,1),R2B(dp,12,1),R2B(dp,13,1));
963
964
                /* Top edge across */
965
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag) || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
966
0
                    int*pp = MACROBLK_UP3(image,ch,tx,idx-1).data;
967
0
                    _jxr_4OverlapFilter(R2B(pp,14,0),R2B(pp,15,0),R2B(dp,0,0),R2B(dp,1,0));
968
0
                    _jxr_4OverlapFilter(R2B(pp,14,1),R2B(pp,15,1),R2B(dp,0,1),R2B(dp,1,1));
969
0
                }
970
0
            }
971
972
            /* Top left corner */
973
0
            if(tx == 0 || image->disableTileOverlapFlag)
974
0
            {
975
0
                int *dp = MACROBLK_UP3(image,ch, tx, 0).data;
976
0
                _jxr_4OverlapFilter(R2B(dp, 0,0),R2B(dp, 1,0),R2B(dp, 0,1),R2B(dp, 1,1));
977
0
            }
978
            /* Top right corner */
979
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
980
0
            {
981
0
                int *dp = MACROBLK_UP3(image,ch,tx, image->tile_column_width[tx] - 1 ).data;
982
0
                _jxr_4OverlapFilter(R2B(dp, 14,0),R2B(dp, 15,0),R2B(dp, 14,1),R2B(dp, 15,1));
983
0
            }
984
985
0
        }
986
987
        /* Bottom edge */
988
0
        if ((top_my+1) == (int) EXTENDED_HEIGHT_BLOCKS(image) || (image->disableTileOverlapFlag && BOTTOM_Y(top_my))) {
989
990
            /* This is the last row, so there is no UP below
991
            TOP. finish up with 4Overlap filters. */
992
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
993
0
            {
994
0
                int*tp = MACROBLK_UP3(image,ch,tx,idx).data;
995
996
0
                _jxr_4OverlapFilter(R2B(tp, 2,14),R2B(tp, 3,14),R2B(tp, 4,14),R2B(tp, 5,14));
997
0
                _jxr_4OverlapFilter(R2B(tp, 6,14),R2B(tp, 7,14),R2B(tp, 8,14),R2B(tp, 9,14));
998
0
                _jxr_4OverlapFilter(R2B(tp,10,14),R2B(tp,11,14),R2B(tp,12,14),R2B(tp,13,14));
999
1000
0
                _jxr_4OverlapFilter(R2B(tp, 2,15),R2B(tp, 3,15),R2B(tp, 4,15),R2B(tp, 5,15));
1001
0
                _jxr_4OverlapFilter(R2B(tp, 6,15),R2B(tp, 7,15),R2B(tp, 8,15),R2B(tp, 9,15));
1002
0
                _jxr_4OverlapFilter(R2B(tp,10,15),R2B(tp,11,15),R2B(tp,12,15),R2B(tp,13,15));
1003
1004
                /* Bottom edge across */
1005
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag)
1006
0
                    || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
1007
0
                        int*tn = MACROBLK_UP3(image,ch,tx,idx-1).data;
1008
0
                        _jxr_4OverlapFilter(R2B(tn,14,14),R2B(tn,15,14),R2B(tp, 0,14),R2B(tp, 1,14));
1009
0
                        _jxr_4OverlapFilter(R2B(tn,14,15),R2B(tn,15,15),R2B(tp, 0,15),R2B(tp, 1,15));
1010
0
                }
1011
0
            }
1012
1013
            /* Bottom left corner */
1014
0
            if(tx == 0 || image->disableTileOverlapFlag)
1015
0
            {
1016
0
                int *dp = MACROBLK_UP3(image,ch,tx,0).data;
1017
0
                _jxr_4OverlapFilter(R2B(dp, 0,14),R2B(dp, 1, 14),R2B(dp, 0,15),R2B(dp, 1, 15));
1018
0
            }
1019
            /* Bottom right corner */
1020
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
1021
0
            {
1022
0
                int *dp = MACROBLK_UP3(image,ch,tx, image->tile_column_width[tx] - 1 ).data;
1023
0
                _jxr_4OverlapFilter(R2B(dp, 14, 14),R2B(dp, 15, 14),R2B(dp, 14,15),R2B(dp, 15, 15));
1024
0
            }
1025
1026
0
        }
1027
1028
0
        for (idx = 0 ; idx < image->tile_column_width[tx] ; idx += 1) {
1029
0
            int jdx;
1030
1031
0
            for (jdx = 2 ; jdx < 14 ; jdx += 4) {
1032
1033
0
                int*dp = MACROBLK_UP3(image,ch,tx,idx).data;
1034
                /* Fully interior 4x4 filter blocks... */
1035
0
                _jxr_4x4OverlapFilter(R2B(dp, 2,jdx+0),R2B(dp, 3,jdx+0),R2B(dp, 4,jdx+0),R2B(dp, 5,jdx+0),
1036
0
                    R2B(dp, 2,jdx+1),R2B(dp, 3,jdx+1),R2B(dp, 4,jdx+1),R2B(dp, 5,jdx+1),
1037
0
                    R2B(dp, 2,jdx+2),R2B(dp, 3,jdx+2),R2B(dp, 4,jdx+2),R2B(dp, 5,jdx+2),
1038
0
                    R2B(dp, 2,jdx+3),R2B(dp, 3,jdx+3),R2B(dp, 4,jdx+3),R2B(dp, 5,jdx+3));
1039
0
                _jxr_4x4OverlapFilter(R2B(dp, 6,jdx+0),R2B(dp, 7,jdx+0),R2B(dp, 8,jdx+0),R2B(dp, 9,jdx+0),
1040
0
                    R2B(dp, 6,jdx+1),R2B(dp, 7,jdx+1),R2B(dp, 8,jdx+1),R2B(dp, 9,jdx+1),
1041
0
                    R2B(dp, 6,jdx+2),R2B(dp, 7,jdx+2),R2B(dp, 8,jdx+2),R2B(dp, 9,jdx+2),
1042
0
                    R2B(dp, 6,jdx+3),R2B(dp, 7,jdx+3),R2B(dp, 8,jdx+3),R2B(dp, 9,jdx+3));
1043
0
                _jxr_4x4OverlapFilter(R2B(dp,10,jdx+0),R2B(dp,11,jdx+0),R2B(dp,12,jdx+0),R2B(dp,13,jdx+0),
1044
0
                    R2B(dp,10,jdx+1),R2B(dp,11,jdx+1),R2B(dp,12,jdx+1),R2B(dp,13,jdx+1),
1045
0
                    R2B(dp,10,jdx+2),R2B(dp,11,jdx+2),R2B(dp,12,jdx+2),R2B(dp,13,jdx+2),
1046
0
                    R2B(dp,10,jdx+3),R2B(dp,11,jdx+3),R2B(dp,12,jdx+3),R2B(dp,13,jdx+3));
1047
1048
0
                if ( (image->tile_column_position[tx] + idx < EXTENDED_WIDTH_BLOCKS(image)-1 && !image->disableTileOverlapFlag) ||
1049
0
                    (image->disableTileOverlapFlag && !RIGHT_X(idx))) {
1050
                        /* 4x4 at the right */
1051
0
                        int*np = MACROBLK_UP3(image,ch,tx,idx+1).data;
1052
1053
0
                        _jxr_4x4OverlapFilter(R2B(dp,14,jdx+0),R2B(dp,15,jdx+0),R2B(np, 0,jdx+0),R2B(np, 1,jdx+0),
1054
0
                            R2B(dp,14,jdx+1),R2B(dp,15,jdx+1),R2B(np, 0,jdx+1),R2B(np, 1,jdx+1),
1055
0
                            R2B(dp,14,jdx+2),R2B(dp,15,jdx+2),R2B(np, 0,jdx+2),R2B(np, 1,jdx+2),
1056
0
                            R2B(dp,14,jdx+3),R2B(dp,15,jdx+3),R2B(np, 0,jdx+3),R2B(np, 1,jdx+3));
1057
0
                }
1058
0
            }
1059
1060
0
            if ((top_my+1) < (int) EXTENDED_HEIGHT_BLOCKS(image)) {
1061
1062
0
                int*dp = MACROBLK_UP3(image,ch,tx,idx).data;
1063
0
                int*up = MACROBLK_UP2(image,ch,tx,idx).data;
1064
1065
0
                if ((tx == 0 && idx==0 && !image->disableTileOverlapFlag) ||
1066
0
                    (image->disableTileOverlapFlag && LEFT_X(idx) && !BOTTOM_Y(top_my))) {
1067
                        /* Across vertical blocks, left edge */
1068
0
                        _jxr_4OverlapFilter(R2B(dp,0,14),R2B(dp,0,15),R2B(up,0,0),R2B(up,0,1));
1069
0
                        _jxr_4OverlapFilter(R2B(dp,1,14),R2B(dp,1,15),R2B(up,1,0),R2B(up,1,1));
1070
0
                }
1071
0
                if((!image->disableTileOverlapFlag) || (image->disableTileOverlapFlag && !BOTTOM_Y(top_my)))
1072
0
                {
1073
                    /* 4x4 bottom */
1074
0
                    _jxr_4x4OverlapFilter(R2B(dp, 2,14),R2B(dp, 3,14),R2B(dp, 4,14),R2B(dp, 5,14),
1075
0
                        R2B(dp, 2,15),R2B(dp, 3,15),R2B(dp, 4,15),R2B(dp, 5,15),
1076
0
                        R2B(up, 2, 0),R2B(up, 3, 0),R2B(up, 4, 0),R2B(up, 5, 0),
1077
0
                        R2B(up, 2, 1),R2B(up, 3, 1),R2B(up, 4, 1),R2B(up, 5, 1));
1078
0
                    _jxr_4x4OverlapFilter(R2B(dp, 6,14),R2B(dp, 7,14),R2B(dp, 8,14),R2B(dp, 9,14),
1079
0
                        R2B(dp, 6,15),R2B(dp, 7,15),R2B(dp, 8,15),R2B(dp, 9,15),
1080
0
                        R2B(up, 6, 0),R2B(up, 7, 0),R2B(up, 8, 0),R2B(up, 9, 0),
1081
0
                        R2B(up, 6, 1),R2B(up, 7, 1),R2B(up, 8, 1),R2B(up, 9, 1));
1082
0
                    _jxr_4x4OverlapFilter(R2B(dp,10,14),R2B(dp,11,14),R2B(dp,12,14),R2B(dp,13,14),
1083
0
                        R2B(dp,10,15),R2B(dp,11,15),R2B(dp,12,15),R2B(dp,13,15),
1084
0
                        R2B(up,10, 0),R2B(up,11, 0),R2B(up,12, 0),R2B(up,13, 0),
1085
0
                        R2B(up,10, 1),R2B(up,11, 1),R2B(up,12, 1),R2B(up,13, 1));
1086
0
                }
1087
1088
0
                if (((image->tile_column_position[tx] + idx < EXTENDED_WIDTH_BLOCKS(image)-1) && !image->disableTileOverlapFlag ) ||
1089
0
                    ( image->disableTileOverlapFlag && !RIGHT_X(idx) && !BOTTOM_Y(top_my) )
1090
0
                    ) {
1091
                        /* Blocks that span the MB to the right */
1092
0
                        int*dn = MACROBLK_UP3(image,ch,tx,idx+1).data;
1093
0
                        int*un = MACROBLK_UP2(image,ch,tx,idx+1).data;
1094
1095
                        /* 4x4 on right, below, below-right */
1096
0
                        _jxr_4x4OverlapFilter(R2B(dp,14,14),R2B(dp,15,14),R2B(dn, 0,14),R2B(dn, 1,14),
1097
0
                            R2B(dp,14,15),R2B(dp,15,15),R2B(dn, 0,15),R2B(dn, 1,15),
1098
0
                            R2B(up,14, 0),R2B(up,15, 0),R2B(un, 0, 0),R2B(un, 1, 0),
1099
0
                            R2B(up,14, 1),R2B(up,15, 1),R2B(un, 0, 1),R2B(un, 1, 1));
1100
0
                }
1101
0
                if((image->tile_column_position[tx] + idx == (int) EXTENDED_WIDTH_BLOCKS(image)-1 && !image->disableTileOverlapFlag) ||
1102
0
                    (image->disableTileOverlapFlag && RIGHT_X(idx) && !BOTTOM_Y(top_my)))
1103
0
                {
1104
                    /* Across vertical blocks, right edge */
1105
0
                    _jxr_4OverlapFilter(R2B(dp,14,14),R2B(dp,14,15),R2B(up,14,0),R2B(up,14,1));
1106
0
                    _jxr_4OverlapFilter(R2B(dp,15,14),R2B(dp,15,15),R2B(up,15,0),R2B(up,15,1));
1107
0
                }
1108
0
            }
1109
0
        }
1110
0
    }
1111
0
}
1112
1113
static void overlap_level2_up3_422(jxr_image_t image, int use_my, int ch)
1114
0
{
1115
0
    int tx = 0; /* XXXX */
1116
0
    int top_my = use_my - 3;
1117
0
    int idx;
1118
0
    int ty = 0;
1119
1120
1121
0
    assert(ch > 0 && image->use_clr_fmt == 2/*YUV422*/);
1122
0
    assert(use_my >= 3);
1123
0
    DEBUG("Overlap Level2 for row %d\n", top_my);
1124
1125
    /* Figure out which tile row the current strip of macroblocks belongs to. */
1126
0
    while(top_my > image->tile_row_position[ty]+image->tile_row_height[ty] - 1)
1127
0
        ty++;
1128
1129
1130
1131
0
    for(tx = 0; tx < image->tile_columns; tx++)
1132
0
    {
1133
        /* Left edge */
1134
0
        if (tx == 0 || image->disableTileOverlapFlag)
1135
0
        {
1136
0
            int*dp = MACROBLK_UP3(image,ch,tx,0).data;
1137
0
            _jxr_4OverlapFilter(R2B42(dp,0, 2),R2B42(dp,0, 3),R2B42(dp,0, 4),R2B42(dp,0, 5));
1138
0
            _jxr_4OverlapFilter(R2B42(dp,0, 6),R2B42(dp,0, 7),R2B42(dp,0, 8),R2B42(dp,0, 9));
1139
0
            _jxr_4OverlapFilter(R2B42(dp,0,10),R2B42(dp,0,11),R2B42(dp,0,12),R2B42(dp,0,13));
1140
1141
0
            _jxr_4OverlapFilter(R2B42(dp,1, 2),R2B42(dp,1, 3),R2B42(dp,1, 4),R2B42(dp,1, 5));
1142
0
            _jxr_4OverlapFilter(R2B42(dp,1, 6),R2B42(dp,1, 7),R2B42(dp,1, 8),R2B42(dp,1, 9));
1143
0
            _jxr_4OverlapFilter(R2B42(dp,1,10),R2B42(dp,1,11),R2B42(dp,1,12),R2B42(dp,1,13));
1144
0
        }
1145
1146
        /* Right edge */
1147
0
        if(tx == image->tile_columns -1 || image->disableTileOverlapFlag){
1148
1149
0
            int*dp = MACROBLK_UP3(image,ch,tx,image->tile_column_width[tx]-1).data;
1150
0
            _jxr_4OverlapFilter(R2B42(dp,6,2),R2B42(dp,6,3),R2B42(dp,6,4),R2B42(dp,6,5));
1151
0
            _jxr_4OverlapFilter(R2B42(dp,7,2),R2B42(dp,7,3),R2B42(dp,7,4),R2B42(dp,7,5));
1152
1153
0
            _jxr_4OverlapFilter(R2B42(dp,6,6),R2B42(dp,6,7),R2B42(dp,6,8),R2B42(dp,6,9));
1154
0
            _jxr_4OverlapFilter(R2B42(dp,7,6),R2B42(dp,7,7),R2B42(dp,7,8),R2B42(dp,7,9));
1155
1156
0
            _jxr_4OverlapFilter(R2B42(dp,6,10),R2B42(dp,6,11),R2B42(dp,6,12),R2B42(dp,6,13));
1157
0
            _jxr_4OverlapFilter(R2B42(dp,7,10),R2B42(dp,7,11),R2B42(dp,7,12),R2B42(dp,7,13));
1158
0
        }
1159
1160
        /* Top edge */
1161
0
        if(top_my == 0 || (image->disableTileOverlapFlag && TOP_Y(top_my) ))
1162
0
        {
1163
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
1164
0
            {
1165
0
                int*dp = MACROBLK_UP3(image,ch,tx,idx).data;
1166
1167
0
                _jxr_4OverlapFilter(R2B42(dp, 2,0),R2B42(dp, 3,0),R2B42(dp, 4,0),R2B42(dp, 5,0));
1168
0
                _jxr_4OverlapFilter(R2B42(dp, 2,1),R2B42(dp, 3,1),R2B42(dp, 4,1),R2B42(dp, 5,1));
1169
1170
                /* Top across for soft tiles */
1171
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag) || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
1172
0
                    int*pp = MACROBLK_UP3(image,ch,tx,idx-1).data;
1173
0
                    _jxr_4OverlapFilter(R2B42(pp,6,0),R2B42(pp,7,0),R2B(dp,0,0),R2B42(dp,1,0));
1174
0
                    _jxr_4OverlapFilter(R2B42(pp,6,1),R2B42(pp,7,1),R2B(dp,0,1),R2B42(dp,1,1));
1175
0
                }
1176
0
            }
1177
1178
            /* Top left corner */
1179
0
            if(tx == 0 || image->disableTileOverlapFlag)
1180
0
            {
1181
0
                int *dp = MACROBLK_UP3(image,ch, tx, 0).data;
1182
0
                _jxr_4OverlapFilter(R2B42(dp,0,0),R2B42(dp,1,0),R2B42(dp,0,1),R2B42(dp,1,1));
1183
0
            }
1184
            /* Top right corner */
1185
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
1186
0
            {
1187
0
                int *dp = MACROBLK_UP3(image,ch,tx, image->tile_column_width[tx] - 1 ).data;
1188
0
                _jxr_4OverlapFilter(R2B42(dp,6,0),R2B42(dp,7,0),R2B42(dp,6,1),R2B42(dp,7,1));
1189
0
            }
1190
0
        }
1191
1192
        /* Bottom edge */
1193
0
        if ((top_my+1) == (int) EXTENDED_HEIGHT_BLOCKS(image) || (image->disableTileOverlapFlag && BOTTOM_Y(top_my))) {
1194
1195
            /* This is the last row, so there is no UP below
1196
            TOP. finish up with 4Overlap filters. */
1197
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
1198
0
            {
1199
0
                int*tp = MACROBLK_UP3(image,ch,tx,idx).data;
1200
1201
0
                _jxr_4OverlapFilter(R2B42(tp,2,14),R2B42(tp,3,14),R2B42(tp,4,14),R2B42(tp,5,14));
1202
0
                _jxr_4OverlapFilter(R2B42(tp,2,15),R2B42(tp,3,15),R2B42(tp,4,15),R2B42(tp,5,15));
1203
1204
                /* Bottom across for soft tiles */
1205
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag)
1206
0
                    || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
1207
                        /* Blocks that span the MB to the right */
1208
0
                        int*tn = MACROBLK_UP3(image,ch,tx,idx-1).data;
1209
0
                        _jxr_4OverlapFilter(R2B42(tn,6,14),R2B42(tn,7,14),R2B42(tp,0,14),R2B42(tp,1,14));
1210
0
                        _jxr_4OverlapFilter(R2B42(tn,6,15),R2B42(tn,7,15),R2B42(tp,0,15),R2B42(tp,1,15));
1211
0
                }
1212
0
            }
1213
1214
            /* Bottom left corner */
1215
0
            if(tx == 0 || image->disableTileOverlapFlag)
1216
0
            {
1217
0
                int *dp = MACROBLK_UP3(image,ch,tx,0).data;
1218
0
                _jxr_4OverlapFilter(R2B42(dp,0,14),R2B42(dp,1,14),R2B42(dp,0,15),R2B42(dp,1,15));
1219
0
            }
1220
            /* Bottom right corner */
1221
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
1222
0
            {
1223
0
                int *dp = MACROBLK_UP3(image,ch,tx, image->tile_column_width[tx] - 1 ).data;
1224
0
                _jxr_4OverlapFilter(R2B42(dp,6,14),R2B42(dp,7,14),R2B42(dp,6,15),R2B42(dp,7,15));
1225
0
            }
1226
0
        }
1227
1228
0
        for (idx = 0 ; idx < image->tile_column_width[tx] ; idx += 1) {
1229
0
            int*dp = MACROBLK_UP3(image,ch,tx,idx).data;
1230
1231
            /* Fully interior 4x4 filter blocks... */
1232
0
            _jxr_4x4OverlapFilter(R2B42(dp,2,2),R2B42(dp,3,2),R2B42(dp,4,2),R2B42(dp,5,2),
1233
0
                R2B42(dp,2,3),R2B42(dp,3,3),R2B42(dp,4,3),R2B42(dp,5,3),
1234
0
                R2B42(dp,2,4),R2B42(dp,3,4),R2B42(dp,4,4),R2B42(dp,5,4),
1235
0
                R2B42(dp,2,5),R2B42(dp,3,5),R2B42(dp,4,5),R2B42(dp,5,5));
1236
1237
0
            _jxr_4x4OverlapFilter(R2B42(dp,2,6),R2B42(dp,3,6),R2B42(dp,4,6),R2B42(dp,5,6),
1238
0
                R2B42(dp,2,7),R2B42(dp,3,7),R2B42(dp,4,7),R2B42(dp,5,7),
1239
0
                R2B42(dp,2,8),R2B42(dp,3,8),R2B42(dp,4,8),R2B42(dp,5,8),
1240
0
                R2B42(dp,2,9),R2B42(dp,3,9),R2B42(dp,4,9),R2B42(dp,5,9));
1241
1242
0
            _jxr_4x4OverlapFilter(R2B42(dp,2,10),R2B42(dp,3,10),R2B42(dp,4,10),R2B42(dp,5,10),
1243
0
                R2B42(dp,2,11),R2B42(dp,3,11),R2B42(dp,4,11),R2B42(dp,5,11),
1244
0
                R2B42(dp,2,12),R2B42(dp,3,12),R2B42(dp,4,12),R2B42(dp,5,12),
1245
0
                R2B42(dp,2,13),R2B42(dp,3,13),R2B42(dp,4,13),R2B42(dp,5,13));
1246
1247
0
            if ( (image->tile_column_position[tx] + idx < EXTENDED_WIDTH_BLOCKS(image)-1 && !image->disableTileOverlapFlag) ||
1248
0
                (image->disableTileOverlapFlag && !RIGHT_X(idx))) {
1249
                    /* Blocks that span the MB to the right */
1250
0
                    int*np = MACROBLK_UP3(image,ch,tx,idx+1).data;
1251
0
                    _jxr_4x4OverlapFilter(R2B42(dp,6,2),R2B42(dp,7,2),R2B42(np,0,2),R2B42(np,1,2),
1252
0
                        R2B42(dp,6,3),R2B42(dp,7,3),R2B42(np,0,3),R2B42(np,1,3),
1253
0
                        R2B42(dp,6,4),R2B42(dp,7,4),R2B42(np,0,4),R2B42(np,1,4),
1254
0
                        R2B42(dp,6,5),R2B42(dp,7,5),R2B42(np,0,5),R2B42(np,1,5));
1255
1256
0
                    _jxr_4x4OverlapFilter(R2B42(dp,6,6),R2B42(dp,7,6),R2B42(np,0,6),R2B42(np,1,6),
1257
0
                        R2B42(dp,6,7),R2B42(dp,7,7),R2B42(np,0,7),R2B42(np,1,7),
1258
0
                        R2B42(dp,6,8),R2B42(dp,7,8),R2B42(np,0,8),R2B42(np,1,8),
1259
0
                        R2B42(dp,6,9),R2B42(dp,7,9),R2B42(np,0,9),R2B42(np,1,9));
1260
1261
0
                    _jxr_4x4OverlapFilter(R2B42(dp,6,10),R2B42(dp,7,10),R2B42(np,0,10),R2B42(np,1,10),
1262
0
                        R2B42(dp,6,11),R2B42(dp,7,11),R2B42(np,0,11),R2B42(np,1,11),
1263
0
                        R2B42(dp,6,12),R2B42(dp,7,12),R2B42(np,0,12),R2B42(np,1,12),
1264
0
                        R2B42(dp,6,13),R2B42(dp,7,13),R2B42(np,0,13),R2B42(np,1,13));
1265
0
            }
1266
1267
0
            if ((top_my+1) < (int) EXTENDED_HEIGHT_BLOCKS(image)) {
1268
1269
                /* Blocks that MB below */
1270
0
                int*dp = MACROBLK_UP3(image,ch,tx,idx).data;
1271
0
                int*up = MACROBLK_UP2(image,ch,tx,idx).data;
1272
1273
0
                if ((tx == 0 && idx==0 && !image->disableTileOverlapFlag) ||
1274
0
                    (image->disableTileOverlapFlag && LEFT_X(idx) && !BOTTOM_Y(top_my))) {
1275
0
                        _jxr_4OverlapFilter(R2B42(dp,0,14),R2B42(dp,0,15),R2B42(up,0,0),R2B42(up,0,1));
1276
0
                        _jxr_4OverlapFilter(R2B42(dp,1,14),R2B42(dp,1,15),R2B42(up,1,0),R2B42(up,1,1));
1277
0
                }
1278
0
                if((!image->disableTileOverlapFlag) || (image->disableTileOverlapFlag && !BOTTOM_Y(top_my)))
1279
0
                {
1280
0
                    _jxr_4x4OverlapFilter(R2B42(dp,2,14),R2B42(dp,3,14),R2B42(dp,4,14),R2B42(dp,5,14),
1281
0
                        R2B42(dp,2,15),R2B42(dp,3,15),R2B42(dp,4,15),R2B42(dp,5,15),
1282
0
                        R2B42(up,2, 0),R2B42(up,3, 0),R2B42(up,4, 0),R2B42(up,5, 0),
1283
0
                        R2B42(up,2, 1),R2B42(up,3, 1),R2B42(up,4, 1),R2B42(up,5, 1));
1284
1285
0
                }
1286
1287
0
                if (((image->tile_column_position[tx] + idx < EXTENDED_WIDTH_BLOCKS(image)-1) && !image->disableTileOverlapFlag ) ||
1288
0
                    ( image->disableTileOverlapFlag && !RIGHT_X(idx) && !BOTTOM_Y(top_my) )
1289
0
                    ) {
1290
                        /* Blocks that span the MB to the right, below, below-right */
1291
0
                        int*dn = MACROBLK_UP3(image,ch,tx,idx+1).data;
1292
0
                        int*un = MACROBLK_UP2(image,ch,tx,idx+1).data;
1293
1294
0
                        _jxr_4x4OverlapFilter(R2B42(dp,6,14),R2B42(dp,7,14),R2B42(dn,0,14),R2B42(dn,1,14),
1295
0
                            R2B42(dp,6,15),R2B42(dp,7,15),R2B42(dn,0,15),R2B42(dn,1,15),
1296
0
                            R2B42(up,6, 0),R2B42(up,7, 0),R2B42(un,0, 0),R2B42(un,1, 0),
1297
0
                            R2B42(up,6, 1),R2B42(up,7, 1),R2B42(un,0, 1),R2B42(un,1, 1));
1298
0
                }
1299
0
                if((image->tile_column_position[tx] + idx == (int) EXTENDED_WIDTH_BLOCKS(image)-1 && !image->disableTileOverlapFlag) ||
1300
0
                    (image->disableTileOverlapFlag && RIGHT_X(idx) && !BOTTOM_Y(top_my)))
1301
0
                {
1302
0
                    _jxr_4OverlapFilter(R2B42(dp,6,14),R2B42(dp,6,15),R2B42(up,6,0),R2B42(up,6,1));
1303
0
                    _jxr_4OverlapFilter(R2B42(dp,7,14),R2B42(dp,7,15),R2B42(up,7,0),R2B42(up,7,1));
1304
0
                }
1305
0
            }
1306
0
        }
1307
0
    }
1308
0
}
1309
/*
1310
*/
1311
1312
static void overlap_level2_up3_420(jxr_image_t image, int use_my, int ch)
1313
0
{
1314
0
    int tx = 0; /* XXXX */
1315
0
    int top_my = use_my - 3;
1316
0
    int idx;
1317
0
    int ty = 0;
1318
1319
0
    assert(ch > 0 && image->use_clr_fmt == 1/*YUV420*/);
1320
0
    assert(use_my >= 3);
1321
1322
0
    DEBUG("Overlap Level2 (YUV420) for row %d\n", top_my);
1323
1324
1325
    /* Figure out which tile row the current strip of macroblocks belongs to. */
1326
0
    while(top_my > image->tile_row_position[ty]+image->tile_row_height[ty] - 1)
1327
0
        ty++;
1328
1329
0
    for(tx = 0; tx < image->tile_columns; tx++)
1330
0
    {
1331
1332
        /* Left edge */
1333
0
        if (tx == 0 || image->disableTileOverlapFlag)
1334
0
        {
1335
0
            int*dp = MACROBLK_UP3(image,ch,tx,0).data;
1336
0
            _jxr_4OverlapFilter(R2B42(dp,0,2),R2B42(dp,0,3),R2B42(dp,0,4),R2B42(dp,0,5));
1337
0
            _jxr_4OverlapFilter(R2B42(dp,1,2),R2B42(dp,1,3),R2B42(dp,1,4),R2B42(dp,1,5));
1338
0
        }
1339
1340
        /* Right edge */
1341
0
        if(tx == image->tile_columns -1 || image->disableTileOverlapFlag){
1342
0
            int*dp = MACROBLK_UP3(image,ch,tx,image->tile_column_width[tx]-1).data;
1343
0
            _jxr_4OverlapFilter(R2B42(dp,6,2),R2B42(dp,6,3),R2B42(dp,6,4),R2B42(dp,6,5));
1344
0
            _jxr_4OverlapFilter(R2B42(dp,7,2),R2B42(dp,7,3),R2B42(dp,7,4),R2B42(dp,7,5));
1345
0
        }
1346
1347
        /* Top edge */
1348
0
        if(top_my == 0 )/* || (image->disableTileOverlapFlag && TOP_Y(top_my) )) */
1349
0
        {
1350
            /* If this is the very first strip of blocks, then process the
1351
            first two scan lines with the smaller 4Overlap filter. */
1352
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
1353
0
            {
1354
0
                int*dp = MACROBLK_UP3(image,ch,tx,idx).data;
1355
0
                _jxr_4OverlapFilter(R2B42(dp, 2,0),R2B42(dp, 3,0),R2B42(dp, 4,0),R2B42(dp, 5,0));
1356
0
                _jxr_4OverlapFilter(R2B42(dp, 2,1),R2B42(dp, 3,1),R2B42(dp, 4,1),R2B42(dp, 5,1));
1357
                /* Top edge across */
1358
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag) || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
1359
0
                    int*pp = MACROBLK_UP3(image,ch,tx,idx-1).data;
1360
0
                    _jxr_4OverlapFilter(R2B42(pp,6,0),R2B42(pp,7,0),R2B(dp,0,0),R2B42(dp,1,0));
1361
0
                    _jxr_4OverlapFilter(R2B42(pp,6,1),R2B42(pp,7,1),R2B(dp,0,1),R2B42(dp,1,1));
1362
0
                }
1363
0
            }
1364
1365
            /* Top left corner */
1366
0
            if(tx == 0 || image->disableTileOverlapFlag)
1367
0
            {
1368
0
                int *dp = MACROBLK_UP3(image,ch,tx,0).data;
1369
0
                _jxr_4OverlapFilter(R2B42(dp, 0,0),R2B42(dp, 1, 0),R2B42(dp, 0 ,1),R2B42(dp, 1,1));
1370
0
            }
1371
            /* Top right corner */
1372
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
1373
0
            {
1374
0
                int *dp = MACROBLK_UP3(image,ch,tx, image->tile_column_width[tx] - 1 ).data;
1375
0
                _jxr_4OverlapFilter(R2B42(dp, 6,0),R2B42(dp, 7,0),R2B42(dp, 6,1),R2B42(dp, 7,1));;
1376
0
            }
1377
1378
0
        }
1379
1380
        /* Bottom edge */
1381
0
        if ((top_my+1) == (int) EXTENDED_HEIGHT_BLOCKS(image) || (image->disableTileOverlapFlag && BOTTOM_Y(top_my))) {
1382
1383
            /* This is the last row, so there is no UP below
1384
            TOP. finish up with 4Overlap filters. */
1385
0
            for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
1386
0
            {
1387
0
                int*tp = MACROBLK_UP3(image,ch,tx,idx).data;
1388
1389
0
                _jxr_4OverlapFilter(R2B42(tp,2,6),R2B42(tp,3,6),R2B42(tp,4,6),R2B42(tp,5,6));
1390
0
                _jxr_4OverlapFilter(R2B42(tp,2,7),R2B42(tp,3,7),R2B42(tp,4,7),R2B42(tp,5,7));
1391
1392
1393
                /* Bottom edge across */
1394
0
                if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag)
1395
0
                    || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
1396
0
                        int*tn = MACROBLK_UP3(image,ch,tx,idx-1).data;
1397
0
                        _jxr_4OverlapFilter(R2B42(tn,6,6),R2B42(tn,7,6),R2B42(tp,0,6),R2B42(tp,1,6));
1398
0
                        _jxr_4OverlapFilter(R2B42(tn,6,7),R2B42(tn,7,7),R2B42(tp,0,7),R2B42(tp,1,7));
1399
0
                }
1400
0
            }
1401
1402
            /* Bottom left corner */
1403
0
            if(tx == 0 || image->disableTileOverlapFlag)
1404
0
            {
1405
0
                int *dp = MACROBLK_UP3(image,ch,tx,0).data;
1406
0
                _jxr_4OverlapFilter(R2B42(dp, 0,6),R2B42(dp, 1, 6),R2B42(dp, 0,7),R2B42(dp, 1, 7));
1407
0
            }
1408
1409
            /* Bottom right corner */
1410
0
            if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
1411
0
            {
1412
0
                int *dp = MACROBLK_UP3(image,ch,tx, image->tile_column_width[tx] - 1 ).data;
1413
0
                _jxr_4OverlapFilter(R2B42(dp, 6, 6),R2B42(dp, 7, 6),R2B42(dp, 6, 7),R2B42(dp, 7, 7));
1414
0
            }
1415
1416
0
            if(image->disableTileOverlapFlag && BOTTOM_Y(top_my) && top_my <EXTENDED_HEIGHT_BLOCKS(image)-1)
1417
0
            {
1418
                /* Also process Top edge of next macroblock row */
1419
                /* In the case of YUV 420, the next row of macroblocks needs to be transformed */
1420
                /* before yuv420_to_yuv422 is called */
1421
                /* In the soft tile case the top 2 lines of the MB below are processed by the 2x2 operators spanning the MB below*/
1422
                /* In the case of hard tiles, if this is the bottom most row of MBs in the Hard Tile */
1423
                /* we need to process the top edge of the next hard tile */
1424
                /* Also see HARDTILE_NOTE in yuv420_to_yuv422() */
1425
1426
0
                for (idx = 0; idx < image->tile_column_width[tx] ; idx += 1)
1427
0
                {
1428
0
                    int*dp = MACROBLK_UP2(image,ch,tx,idx).data;
1429
0
                    _jxr_4OverlapFilter(R2B42(dp, 2,0),R2B42(dp, 3,0),R2B42(dp, 4,0),R2B42(dp, 5,0));
1430
0
                    _jxr_4OverlapFilter(R2B42(dp, 2,1),R2B42(dp, 3,1),R2B42(dp, 4,1),R2B42(dp, 5,1));
1431
                    /* Top edge across */
1432
0
                    if ( (image->tile_column_position[tx] + idx > 0 && !image->disableTileOverlapFlag) || (image->disableTileOverlapFlag && !LEFT_X(idx))) {
1433
0
                        int*pp = MACROBLK_UP2(image,ch,tx,idx-1).data;
1434
0
                        _jxr_4OverlapFilter(R2B42(pp,6,0),R2B42(pp,7,0),R2B(dp,0,0),R2B42(dp,1,0));
1435
0
                        _jxr_4OverlapFilter(R2B42(pp,6,1),R2B42(pp,7,1),R2B(dp,0,1),R2B42(dp,1,1));
1436
0
                    }
1437
0
                }
1438
1439
                /* Top left corner */
1440
0
                if(tx == 0 || image->disableTileOverlapFlag)
1441
0
                {
1442
0
                    int *dp = MACROBLK_UP2(image,ch,tx,0).data;
1443
0
                    _jxr_4OverlapFilter(R2B42(dp, 0,0),R2B42(dp, 1, 0),R2B42(dp, 0 ,1),R2B42(dp, 1,1));
1444
0
                }
1445
1446
                /* Top right corner */
1447
0
                if(tx == image->tile_columns -1 || image->disableTileOverlapFlag)
1448
0
                {
1449
0
                    int *dp = MACROBLK_UP2(image,ch,tx, image->tile_column_width[tx] - 1 ).data;
1450
0
                    _jxr_4OverlapFilter(R2B42(dp, 6,0),R2B42(dp, 7,0),R2B42(dp, 6,1),R2B42(dp, 7,1));;
1451
0
                }
1452
0
            }
1453
0
        }
1454
1455
0
        for (idx = 0 ; idx < image->tile_column_width[tx] ; idx += 1) {
1456
1457
0
            int*dp = MACROBLK_UP3(image,ch,tx,idx).data;
1458
            /*int*up = MACROBLK_UP2(image,ch,tx,idx).data; not needed */
1459
1460
            /* Fully interior 4x4 filter blocks... */
1461
0
            _jxr_4x4OverlapFilter(R2B42(dp,2,2),R2B42(dp,3,2),R2B42(dp,4,2),R2B42(dp,5,2),
1462
0
                R2B42(dp,2,3),R2B42(dp,3,3),R2B42(dp,4,3),R2B42(dp,5,3),
1463
0
                R2B42(dp,2,4),R2B42(dp,3,4),R2B42(dp,4,4),R2B42(dp,5,4),
1464
0
                R2B42(dp,2,5),R2B42(dp,3,5),R2B42(dp,4,5),R2B42(dp,5,5));
1465
1466
0
            if ( (image->tile_column_position[tx] + idx < EXTENDED_WIDTH_BLOCKS(image)-1 && !image->disableTileOverlapFlag) ||
1467
0
                (image->disableTileOverlapFlag && !RIGHT_X(idx)))
1468
0
            {
1469
                /* 4x4 at the right */
1470
0
                int*np = MACROBLK_UP3(image,ch,tx,idx+1).data;
1471
1472
0
                _jxr_4x4OverlapFilter(R2B42(dp,6,2),R2B42(dp,7,2),R2B42(np,0,2),R2B42(np,1,2),
1473
0
                    R2B42(dp,6,3),R2B42(dp,7,3),R2B42(np,0,3),R2B42(np,1,3),
1474
0
                    R2B42(dp,6,4),R2B42(dp,7,4),R2B42(np,0,4),R2B42(np,1,4),
1475
0
                    R2B42(dp,6,5),R2B42(dp,7,5),R2B42(np,0,5),R2B42(np,1,5));
1476
0
            }
1477
1478
0
            if ((top_my+1) < (int) EXTENDED_HEIGHT_BLOCKS(image)) {
1479
1480
0
                int*dp = MACROBLK_UP3(image,ch,tx,idx).data;
1481
0
                int*up = MACROBLK_UP2(image,ch,tx,idx).data;
1482
1483
0
                if ((tx == 0 && idx==0 && !image->disableTileOverlapFlag) ||
1484
0
                    (image->disableTileOverlapFlag && LEFT_X(idx) && !BOTTOM_Y(top_my))) {
1485
                        /* Across vertical blocks, left edge */
1486
0
                        _jxr_4OverlapFilter(R2B42(dp,0,6),R2B42(dp,0,7),R2B42(up,0,0),R2B42(up,0,1));
1487
0
                        _jxr_4OverlapFilter(R2B42(dp,1,6),R2B42(dp,1,7),R2B42(up,1,0),R2B42(up,1,1));
1488
0
                }
1489
0
                if((!image->disableTileOverlapFlag) || (image->disableTileOverlapFlag && !BOTTOM_Y(top_my)))
1490
0
                {
1491
                    /* 4x4 straddling lower MB */
1492
0
                    _jxr_4x4OverlapFilter(R2B42(dp,2,6),R2B42(dp,3,6),R2B42(dp,4,6),R2B42(dp,5,6),
1493
0
                        R2B42(dp,2,7),R2B42(dp,3,7),R2B42(dp,4,7),R2B42(dp,5,7),
1494
0
                        R2B42(up,2,0),R2B42(up,3,0),R2B42(up,4,0),R2B42(up,5,0),
1495
0
                        R2B42(up,2,1),R2B42(up,3,1),R2B42(up,4,1),R2B42(up,5,1));
1496
0
                }
1497
1498
0
                if (((image->tile_column_position[tx] + idx < EXTENDED_WIDTH_BLOCKS(image)-1) && !image->disableTileOverlapFlag ) ||
1499
0
                    ( image->disableTileOverlapFlag && !RIGHT_X(idx) && !BOTTOM_Y(top_my) )
1500
0
                    ) {
1501
                        /* Blocks that span the MB to the right */
1502
0
                        int*dn = MACROBLK_UP3(image,ch,tx,idx+1).data;
1503
0
                        int*un = MACROBLK_UP2(image,ch,tx,idx+1).data;
1504
1505
                        /* 4x4 right, below, below-right */
1506
0
                        _jxr_4x4OverlapFilter(R2B42(dp,6,6),R2B42(dp,7,6),R2B42(dn,0,6),R2B42(dn,1,6),
1507
0
                            R2B42(dp,6,7),R2B42(dp,7,7),R2B42(dn,0,7),R2B42(dn,1,7),
1508
0
                            R2B42(up,6,0),R2B42(up,7,0),R2B42(un,0,0),R2B42(un,1,0),
1509
0
                            R2B42(up,6,1),R2B42(up,7,1),R2B42(un,0,1),R2B42(un,1,1));
1510
0
                }
1511
0
                if((image->tile_column_position[tx] + idx == (int) EXTENDED_WIDTH_BLOCKS(image)-1 && !image->disableTileOverlapFlag) ||
1512
0
                    (image->disableTileOverlapFlag && RIGHT_X(idx) && !BOTTOM_Y(top_my)))
1513
0
                {
1514
                    /* Across vertical blocks, right edge */
1515
0
                    _jxr_4OverlapFilter(R2B42(dp,6,6),R2B42(dp,6,7),R2B42(up,6,0),R2B42(up,6,1));
1516
0
                    _jxr_4OverlapFilter(R2B42(dp,7,6),R2B42(dp,7,7),R2B42(up,7,0),R2B42(up,7,1));
1517
0
                }
1518
0
            }
1519
0
        }
1520
0
    }
1521
0
}
1522
1523
1524
static void overlap_level2_up3(jxr_image_t image, int use_my, int ch)
1525
0
{
1526
0
    if (ch == 0) {
1527
0
        overlap_level2_up3_444(image, use_my, ch);
1528
0
    }
1529
0
    else {
1530
0
        switch (image->use_clr_fmt) {
1531
0
            case 1: /*YUV420*/
1532
0
                overlap_level2_up3_420(image, use_my, ch);
1533
0
                break;
1534
0
            case 2: /*YUV422*/
1535
0
                overlap_level2_up3_422(image, use_my, ch);
1536
0
                break;
1537
0
            default:
1538
0
                overlap_level2_up3_444(image, use_my, ch);
1539
0
                break;
1540
0
        }
1541
0
    }
1542
0
}
1543
1544
1545
static void yuv444_to_rgb(jxr_image_t image, int mx)
1546
0
{
1547
0
    int px;
1548
0
    for (px = 0 ; px < 256 ; px += 1) {
1549
0
        int Y = image->strip[0].up3[mx].data[px];
1550
0
        int U = image->strip[1].up3[mx].data[px];
1551
0
        int V = image->strip[2].up3[mx].data[px];
1552
0
        int G = Y - _jxr_floor_div2(-U);
1553
0
        int R = G - U - _jxr_ceil_div2(V);
1554
0
        int B = V + R;
1555
1556
0
        image->strip[0].up3[mx].data[px] = R;
1557
0
        image->strip[1].up3[mx].data[px] = G;
1558
0
        image->strip[2].up3[mx].data[px] = B;
1559
0
    }
1560
0
}
1561
1562
static const int iH[5][4] = {{4, 4 , 0, 8}, {5, 3, 1, 7}, {6, 2, 2, 6}, {7, 1, 3, 5}, {8, 0, 4, 4}};
1563
1564
static void upsample(int inbuf[], int outbuf[], int upsamplelen, int chroma_center)
1565
0
{
1566
0
    int k;
1567
0
    if(chroma_center == 5 || chroma_center == 6 || chroma_center == 7)
1568
0
    {
1569
0
        chroma_center = 0;
1570
0
        DEBUG("Treating chroma_center as 0 in upsample\n");
1571
0
    }
1572
1573
0
    for (k = 0; k <= (upsamplelen - 2) / 2; k++)
1574
0
        outbuf[2*k+1] = (( iH[chroma_center][0]*inbuf[k+1] + iH[chroma_center][1]*inbuf[k+2] + 4) >> 3);
1575
0
    for (k = -1; k <= (upsamplelen - 4) / 2; k++)
1576
0
        outbuf[2*k+2] = ((iH[chroma_center][2] * inbuf[k+1] + iH[chroma_center][3] * inbuf[k+2] + 4) >> 3);
1577
0
}
1578
1579
static void yuv422_to_yuv444(jxr_image_t image, int mx)
1580
0
{
1581
0
    int buf[256];
1582
1583
0
    int ch;
1584
0
    int px, py, idx;
1585
1586
    //printf("YUV420 chroma centering is %d:%d\n",image->chroma_centering_x,image->chroma_centering_y);
1587
1588
0
    for(ch =1; ch < 3; ch ++) {
1589
1590
0
        for (py = 0 ; py < 16 ; py += 1)
1591
0
        {
1592
0
            int inbuf [10];
1593
1594
0
            if(mx == 0) /* Repeat to the left */
1595
0
                image->strip[ch].upsample_memory_x[py] = image->strip[ch].up3[mx].data[8*py];
1596
1597
            /* Prep input array */
1598
0
            for(px =0; px <=7; px++)
1599
0
            {
1600
0
                inbuf[px+1] = image->strip[ch].up3[mx].data[8*py+ px];
1601
1602
0
            }
1603
0
            inbuf[0] =  image->strip[ch].upsample_memory_x[py];
1604
0
            if(mx+1 < (int) EXTENDED_WIDTH_BLOCKS(image))
1605
0
                inbuf[9] = image->strip[ch].up3[mx+1].data[8*py];
1606
0
            else
1607
0
                inbuf[9] = inbuf[8]; /* Repeat to the right */
1608
1609
            /* Call upsample */
1610
0
            upsample(inbuf, buf + 16*py, 16, image->chroma_centering_x);
1611
1612
            /* Remember right most vals */
1613
0
            image->strip[ch].upsample_memory_x[py] = image->strip[ch].up3[mx].data[8*py+7];
1614
0
        }
1615
1616
0
        for (idx = 0 ; idx < 256 ; idx += 1)
1617
0
            image->strip[ch].up3[mx].data[idx] = buf[idx];
1618
1619
0
    }
1620
0
}
1621
1622
static void yuv420_to_yuv444(jxr_image_t image, int use_my, int mx)
1623
0
{
1624
0
    int buf[256];
1625
0
    int intermediatebuf[2][16 * 8];
1626
1627
0
    int ch;
1628
0
    int inbuf [10];
1629
0
    int px, py, idx;
1630
1631
    //printf("YUV420 chroma centering is %d:%d\n",image->chroma_centering_x,image->chroma_centering_y);
1632
1633
    /* Upsample in the y direction */
1634
0
    for (ch = 1 ; ch < 3 ; ch += 1) {
1635
0
        for(px = 0; px < 8; px ++)
1636
0
        {
1637
0
            if(use_my-2 == 1) /* Repeat to the top */
1638
0
                image->strip[ch].upsample_memory_y[8*mx+ px] = image->strip[ch].up3[mx].data[px];/* Store the top most values */
1639
1640
            /* Prep input buffer */
1641
0
            for(py =0; py < 8 ; py++)
1642
0
                inbuf[py+1] = image->strip[ch].up3[mx].data[8*py+ px];
1643
0
            inbuf[0] = image->strip[ch].upsample_memory_y[8*mx + px];
1644
0
            if((use_my-2) < (int) EXTENDED_HEIGHT_BLOCKS(image))
1645
0
            {
1646
0
                if(px <= 3)
1647
0
                    inbuf[9] = image->strip[ch].up2[mx].data[px]; /* Get the lower MB sample */
1648
0
                else
1649
0
                    inbuf[9] = image->strip[ch].up2[mx].data[px + 12]; /* Since unblock_shuffle420 has not been called on up2 */
1650
0
            }
1651
0
            else
1652
0
                inbuf[9] = inbuf[8]; /* Repeat to the right */
1653
1654
            /* Call upsample */
1655
0
            upsample(inbuf, buf, 16, image->chroma_centering_y);
1656
1657
0
            for(py =0; py < 16; py ++)
1658
0
                intermediatebuf[ch-1][8*py + px] = buf[py];
1659
1660
0
            image->strip[ch].upsample_memory_y[8*mx + px] = image->strip[ch].up3[mx].data[8*7+px];/* Store the bottom most values */
1661
0
        }
1662
0
    }
1663
1664
    /* Upsample in the X direction */
1665
0
    for (ch = 1 ; ch < 3 ; ch += 1) {
1666
0
        int nextmbrow[16];
1667
1668
        /* To upsample in the X direction, we need the Y-direction upsampled values from the left most row of the next MB */
1669
        /* Prep input buffer */
1670
0
        for(py = 0; py < 8; py ++)
1671
0
        {
1672
0
            if(mx + 1 < (int) EXTENDED_WIDTH_BLOCKS(image))
1673
0
                inbuf[py + 1] = image->strip[ch].up3[mx+1].data[8*py];
1674
0
            else
1675
0
                inbuf[py + 1] = image->strip[ch].up3[mx].data[8*py];
1676
0
        }
1677
0
        if(use_my - 2 < (int) EXTENDED_HEIGHT_BLOCKS(image) && mx + 1 < (int) EXTENDED_WIDTH_BLOCKS(image))
1678
0
            inbuf[9] = image->strip[ch].up2[mx+1].data[0];
1679
0
        else
1680
0
            inbuf[9] = inbuf[8];/* Repeat to the right */
1681
0
        if(use_my -2 != 1 && mx + 1 < (int) EXTENDED_WIDTH_BLOCKS(image))
1682
0
            inbuf[0] = image->strip[ch].upsample_memory_y[8*(mx+1)];
1683
0
        else
1684
0
            inbuf[0] = inbuf[1];
1685
1686
        /*Call upsample */
1687
0
        upsample(inbuf, nextmbrow, 16, image->chroma_centering_y);
1688
1689
0
        for(py = 0; py < 16; py ++)
1690
0
        {
1691
0
            if(mx == 0) /* Repeat to the left */
1692
0
                image->strip[ch].upsample_memory_x[py] = intermediatebuf[ch-1][8*py];
1693
1694
            /* Prepare the input buffer */
1695
0
            for(px =0; px <=7; px++)
1696
0
                inbuf[px+1] = intermediatebuf[ch-1][8*py+ px];
1697
1698
0
            inbuf[0] = image->strip[ch].upsample_memory_x[py];
1699
0
            if(mx + 1 < (int) EXTENDED_WIDTH_BLOCKS(image))
1700
0
            {
1701
0
                inbuf[9] = nextmbrow[py];
1702
0
            }
1703
0
            else
1704
0
                inbuf[9] = inbuf[8]; /* Repeat to the right */
1705
1706
            /* Call upsample */
1707
0
            upsample(inbuf, buf + 16*py, 16, image->chroma_centering_x);
1708
0
            image->strip[ch].upsample_memory_x[py] = intermediatebuf[ch-1][8*py + 7];/* Store the right most values */
1709
0
        }
1710
1711
0
        for(idx =0; idx < 256; idx ++)
1712
0
            image->strip[ch].up3[mx].data[idx] = buf[idx];
1713
0
    }
1714
0
}
1715
1716
static void yuvk_to_cmyk(jxr_image_t image, int mx)
1717
0
{
1718
0
    int px;
1719
0
    for (px = 0 ; px < 256 ; px += 1) {
1720
0
        int Y = image->strip[0].up3[mx].data[px];
1721
0
        int U = image->strip[1].up3[mx].data[px];
1722
0
        int V = image->strip[2].up3[mx].data[px];
1723
0
        int K = image->strip[3].up3[mx].data[px];
1724
0
        int k = K + _jxr_floor_div2(Y);
1725
0
        int m = k - Y - _jxr_floor_div2(U);
1726
0
        int c = U + m + _jxr_floor_div2(V);
1727
0
        int y = c - V;
1728
1729
0
        image->strip[0].up3[mx].data[px] = c;
1730
0
        image->strip[1].up3[mx].data[px] = m;
1731
0
        image->strip[2].up3[mx].data[px] = y;
1732
0
        image->strip[3].up3[mx].data[px] = k;
1733
0
    }
1734
0
}
1735
1736
static void yuvk_to_cmykdirect(jxr_image_t image, int mx)
1737
0
{
1738
0
    int px;
1739
0
    for (px = 0 ; px < 256 ; px += 1) {
1740
0
        int y = image->strip[0].up3[mx].data[px];
1741
0
        int u = image->strip[1].up3[mx].data[px];
1742
0
        int v = image->strip[2].up3[mx].data[px];
1743
0
        int k = image->strip[3].up3[mx].data[px];
1744
1745
0
        image->strip[0].up3[mx].data[px] = u;
1746
0
        image->strip[1].up3[mx].data[px] = v;
1747
0
        image->strip[2].up3[mx].data[px] = k;
1748
0
        image->strip[3].up3[mx].data[px] = y;
1749
0
    }
1750
0
}
1751
1752
static int PostScalingFloat(int iPixVal, unsigned int expBias, unsigned char lenMantissa, int bitdepth)
1753
0
{
1754
0
    int convVal = 0;
1755
0
    if (bitdepth == JXR_BD16F)
1756
0
    {
1757
0
        uint8_t iS = 0;
1758
0
        unsigned int iEM = (iPixVal >= 0)?(iPixVal):(-iPixVal);
1759
0
        if(iPixVal < 0)
1760
0
            iS = 1;
1761
0
        if (iEM > 0x7FFF)
1762
0
            iEM = 0x7FFF;
1763
0
        convVal = ((iS << 15) | iEM); /* Concatenate these fields*/
1764
0
    }
1765
0
    else
1766
0
    {
1767
0
        int sign, iTempH, mantissa, exp, lmshift = (1 << lenMantissa);
1768
1769
0
        assert (expBias <= 127);
1770
1771
0
        iTempH = (int) iPixVal ;
1772
0
        sign = (iTempH >> 31);
1773
0
        iTempH = (iTempH ^ sign) - sign; /* abs(iTempH) */
1774
1775
0
        exp = (unsigned int) iTempH >> lenMantissa;/* & ((1 << (31 - lenMantissa)) - 1); */
1776
0
        mantissa = (iTempH & (lmshift - 1)) | lmshift; /* actual mantissa, with normalizer */
1777
0
        if (exp == 0) { /* denormal land */
1778
0
            mantissa ^= lmshift; /* normalizer removed */
1779
0
            exp = 1; /* actual exponent */
1780
0
        }
1781
1782
0
        exp += (127 - expBias);
1783
0
        while (mantissa < lmshift && exp > 1 && mantissa > 0) { /* denormal originally, see if normal is possible */
1784
0
            exp--;
1785
0
            mantissa <<= 1;
1786
0
        }
1787
0
        if (mantissa < lmshift) /* truly denormal */
1788
0
            exp = 0;
1789
0
        else
1790
0
            mantissa ^= lmshift;
1791
0
        mantissa <<= (23 - lenMantissa);
1792
1793
0
        convVal = (sign & 0x80000000) | (exp << 23) | mantissa;
1794
0
    }
1795
0
    return convVal;
1796
0
}
1797
1798
0
static void PostScalingFl2(int arrayOut[], int arrayIn[]) {
1799
        /* arrayIn[ ]= {R, G, B} */
1800
        /* arrayOut[ ]= {Rrgbe, Grgbe, Brgbe, Ergbe} */
1801
0
    int iEr, iEg, iEb;
1802
0
    int iShift;
1803
1804
0
    if (arrayIn[0] <= 0) {
1805
0
        arrayOut[0] = 0;
1806
0
        iEr = 0;
1807
0
    }
1808
0
    else if ((arrayIn[0] >> 7) > 1) {
1809
0
        arrayOut[0] = (arrayIn[0] & 0x7F) + 0x80;
1810
0
        iEr = (arrayIn[0] >> 7);
1811
0
    }
1812
0
    else {
1813
0
        arrayOut[0] = arrayIn[0];
1814
0
        iEr = 1;
1815
0
    }
1816
0
    if (arrayIn[1] <= 0) {
1817
0
        arrayOut[1] = 0;
1818
0
        iEg = 0;
1819
0
    }
1820
0
    else if ((arrayIn[1] >> 7) > 1) {
1821
0
        arrayOut[1] = (arrayIn[1] & 0x7F) + 0x80;
1822
0
        iEg = (arrayIn[1] >> 7);
1823
0
    }
1824
0
    else {
1825
0
        arrayOut[1] = arrayIn[1];
1826
0
        iEg = 1;
1827
0
    }
1828
0
    if (arrayIn[2] <= 0) {
1829
0
        arrayOut[2] = 0;
1830
0
        iEb = 0;
1831
0
    }
1832
0
    else if ((arrayIn[2] >> 7) > 1) {
1833
0
        arrayOut[2] = (arrayIn[2] & 0x7F) + 0x80;
1834
0
        iEb = (arrayIn[2] >> 7);
1835
0
    }
1836
0
    else {
1837
0
        arrayOut[2] = arrayIn[2];
1838
0
        iEb = 1;
1839
0
    }
1840
1841
    /* Max(iEr, iEg, iEb) */
1842
0
    arrayOut[3] = iEr> iEg? (iEr>iEb?iEr:iEb):(iEg>iEb?iEg:iEb);
1843
1844
0
    if( arrayOut[3] > iEr){
1845
0
        iShift = ( arrayOut[3] - iEr);
1846
0
        arrayOut[0] = (unsigned char)((((int) arrayOut[0]) * 2 + 1) >> (iShift + 1));
1847
0
    }
1848
0
    if( arrayOut[3] > iEg){
1849
0
        iShift = ( arrayOut[3]- iEg);
1850
0
        arrayOut[1] = (unsigned char)((((int) arrayOut[1]) * 2 + 1) >> (iShift + 1));
1851
0
    }
1852
0
    if( arrayOut[3] > iEb){
1853
0
        iShift = ( arrayOut[3]- iEb);
1854
0
        arrayOut[2] = (unsigned char)((((int) arrayOut[2]) * 2 + 1) >> (iShift + 1));
1855
0
    }
1856
0
}
1857
1858
/*
1859
** Output shift/clip routines, helpers for emit
1860
*/
1861
1862
static void shift_and_clip_CMYK(jxr_image_t image,int idx,
1863
                                int bias,int shift_bits,int scale,int round,int clip_low,int clip_hig)
1864
0
{
1865
0
 int *dp;
1866
0
 int jdx,ch;
1867
1868
0
 for (ch = 0 ; ch < 3 ; ch += 1) {
1869
0
   dp = image->strip[ch].up3[idx].data;
1870
0
   for (jdx = 0 ; jdx < 256 ; jdx += 1) {
1871
0
     dp[jdx] = (dp[jdx] + ((bias>>(shift_bits+1))<<scale) + round) >> scale;
1872
0
     dp[jdx] <<= shift_bits;
1873
0
     if (dp[jdx] > clip_hig)
1874
0
       dp[jdx] = clip_hig;
1875
0
     if (dp[jdx] < clip_low)
1876
0
       dp[jdx] = clip_low;
1877
0
   }
1878
0
 }
1879
0
 dp = image->strip[3].up3[idx].data;
1880
0
 for (jdx = 0 ; jdx < 256 ; jdx += 1) {
1881
0
   dp[jdx] = (dp[jdx] - ((bias>>(shift_bits+1))<<scale) + round) >> scale;
1882
0
   dp[jdx] <<= shift_bits;
1883
0
   if (dp[jdx] > clip_hig)
1884
0
     dp[jdx] = clip_hig;
1885
0
   if (dp[jdx] < clip_low)
1886
0
     dp[jdx] = clip_low;
1887
0
 }
1888
0
}
1889
1890
static void shift_and_clip_BD565(jxr_image_t image,int idx,int bias,int scale,int round)
1891
0
{
1892
  /* Special case where R and B have different clip thresholds from G,
1893
  ** special case where red and blue are swapped by default.
1894
  */
1895
0
  int jdx;
1896
0
  int *dp0 = image->strip[0].up3[idx].data;
1897
0
  int *dp1 = image->strip[1].up3[idx].data;
1898
0
  int *dp2 = image->strip[2].up3[idx].data;
1899
1900
0
  for (jdx = 0 ; jdx < 256 ; jdx += 1) {
1901
0
    int i0 = (dp0[jdx] + (bias<<scale) + round) >> (scale + 1);
1902
0
    int i1 = (dp1[jdx] + (bias<<scale) + round) >> (scale + 0); /* green is special */
1903
0
    int i2 = (dp2[jdx] + (bias<<scale) + round) >> (scale + 1);
1904
1905
0
    if (i0 > 31) i0 = 31;
1906
0
    if (i0 <  0) i0 = 0;
1907
0
    if (i1 > 63) i1 = 63;
1908
0
    if (i1 <  0) i1 = 0;
1909
0
    if (i2 > 31) i2 = 31;
1910
0
    if (i2 <  0) i2 = 0;
1911
    //
1912
0
    if (RB_SWAPPED(image)) {
1913
0
      dp0[jdx] = i2;
1914
0
      dp1[jdx] = i1;
1915
0
      dp2[jdx] = i0;
1916
0
    } else {
1917
0
      dp0[jdx] = i0;
1918
0
      dp1[jdx] = i1;
1919
0
      dp2[jdx] = i2;
1920
0
    }
1921
0
  }
1922
0
}
1923
1924
static void shift_and_clip_BDxxx(jxr_image_t image,int idx,
1925
                                 int bias,int shift_bits,int scale,int round,int clip_low,int clip_hig)
1926
0
{
1927
  /* special case where red and blue are swapped by default.
1928
  */
1929
0
  int jdx;
1930
0
  int *dp0 = image->strip[0].up3[idx].data;
1931
0
  int *dp1 = image->strip[1].up3[idx].data;
1932
0
  int *dp2 = image->strip[2].up3[idx].data;
1933
1934
1935
0
  for (jdx = 0 ; jdx < 256 ; jdx += 1) {
1936
0
    int i0 = (dp0[jdx] + ((bias>>shift_bits)<<scale) + round) >> scale;
1937
0
    int i1 = (dp1[jdx] + ((bias>>shift_bits)<<scale) + round) >> scale;
1938
0
    int i2 = (dp2[jdx] + ((bias>>shift_bits)<<scale) + round) >> scale;
1939
1940
0
    i0 <<= shift_bits;
1941
0
    if (i0 > clip_hig) i0 = clip_hig;
1942
0
    if (i0 < clip_low) i0 = clip_low;
1943
1944
0
    i1 <<= shift_bits;
1945
0
    if (i1 > clip_hig) i1 = clip_hig;
1946
0
    if (i1 < clip_low) i1 = clip_low;
1947
1948
0
    i2 <<= shift_bits;
1949
0
    if (i2 > clip_hig) i2 = clip_hig;
1950
0
    if (i2 < clip_low) i2 = clip_low;
1951
    //
1952
0
    if (RB_SWAPPED(image)) {
1953
0
      dp0[jdx] = i2;
1954
0
      dp1[jdx] = i1;
1955
0
      dp2[jdx] = i0;
1956
0
    } else {
1957
0
      dp0[jdx] = i0;
1958
0
      dp1[jdx] = i1;
1959
0
      dp2[jdx] = i2;
1960
0
    }
1961
0
  }
1962
0
}
1963
1964
static void shift_and_clip_regular(jxr_image_t image,int idx,
1965
                                   int bias,int shift_bits,int scale,int round,int clip_low,int clip_hig)
1966
0
{
1967
  /* The regular case, nothing special here
1968
   */
1969
0
  int ch;
1970
1971
0
  for(ch = 0;ch < image->num_channels;ch++) {
1972
0
    int*dp = image->strip[ch].up3[idx].data;
1973
0
    int jdx;
1974
0
    for (jdx = 0 ; jdx < 256 ; jdx += 1) {
1975
0
      dp[jdx] = (dp[jdx] + ((bias>>shift_bits)<<scale) + round) >> scale;
1976
0
      dp[jdx] <<= shift_bits;
1977
0
      if (dp[jdx] > clip_hig)
1978
0
        dp[jdx] = clip_hig;
1979
0
      if (dp[jdx] < clip_low)
1980
0
        dp[jdx] = clip_low;
1981
0
    }
1982
0
  }
1983
0
}
1984
1985
static void shift_and_clip_FLOAT(jxr_image_t image,int idx,
1986
                                 int scale,int round)
1987
0
{
1988
  /* 16 or 32 bit floating point.
1989
   */
1990
0
  int ch;
1991
0
  for(ch = 0;ch < image->num_channels;ch++) {
1992
0
    int* dp = image->strip[ch].up3[idx].data;
1993
0
    int jdx;
1994
0
    for (jdx = 0 ; jdx < 256 ; jdx += 1) {
1995
0
      dp[jdx] = (dp[jdx] + round) >> scale;
1996
0
      dp[jdx] = PostScalingFloat(dp[jdx], image->exp_bias, image->len_mantissa, SOURCE_BITDEPTH(image));
1997
0
    }
1998
0
  }
1999
0
}
2000
2001
static void shift_and_clip_RGBE(jxr_image_t image,int idx,
2002
                                int scale,int round,int *buffer)
2003
0
{
2004
  /*
2005
  ** RGBE : PostScalingFl2 requires one extra sample per pixel - Write directly into buffer
2006
  */
2007
0
  int jdx;
2008
0
  int *dp0 = image->strip[0].up3[idx].data;
2009
0
  int *dp1 = image->strip[1].up3[idx].data;
2010
0
  int *dp2 = image->strip[2].up3[idx].data;
2011
0
  assert(image->num_channels == 3);
2012
2013
0
  for (jdx = 0 ; jdx < 256 ; jdx += 1) {
2014
    /* There is no bias in this case */
2015
0
    int idp0 = (dp0[jdx] + round) >> scale;
2016
0
    int idp1 = (dp1[jdx] + round) >> scale;
2017
0
    int idp2 = (dp2[jdx] + round) >> scale;
2018
2019
0
    int arrIn[3] = {idp0, idp1, idp2};
2020
2021
0
    PostScalingFl2(buffer + (image->num_channels + 1) * jdx, arrIn);
2022
0
  }
2023
0
}
2024
2025
static void scale_and_emit_top(jxr_image_t image, int tx, int use_my)
2026
0
{
2027
0
    int scale = image->scaled_flag? 3 : 0;
2028
0
    int bias;
2029
0
    int round;
2030
0
    int shift_bits = image->shift_bits;
2031
    /* Clipping based on 8bit values. */
2032
0
    int clip_low = 0;
2033
0
    int clip_hig = 255;
2034
0
    int idx;
2035
0
    int buffer[(MAX_CHANNELS + 1)*256];
2036
0
    unsigned int bSkipColorTransform = 0;
2037
0
    memset(buffer, 0,(MAX_CHANNELS + 1)*256);
2038
2039
0
    switch (SOURCE_BITDEPTH(image)) {
2040
0
        case 0: /* BD1WHITE1*/
2041
2042
0
        case 15: /* BD1BLACK1 */
2043
0
            bias = 0;
2044
0
            round = image->scaled_flag? 4 : 0;
2045
0
            clip_low = 0;
2046
0
            clip_hig = 1;
2047
0
            break;
2048
0
        case 1: /* BD8 */
2049
0
            bias = 1 << 7;
2050
0
            round = image->scaled_flag? 3 : 0;
2051
0
            clip_low = 0;
2052
0
            clip_hig = 255;
2053
0
            break;
2054
0
        case 2: /* BD16 */
2055
0
            bias = 1 << 15;
2056
0
            round = image->scaled_flag? 4 : 0;
2057
0
            clip_low = 0;
2058
0
            clip_hig = 65535;
2059
0
            break;
2060
0
        case 3: /* BD16S */
2061
0
            bias = 0;
2062
0
            round = image->scaled_flag? 3 : 0;
2063
0
            clip_low = -32768;
2064
0
            clip_hig = 32767;
2065
0
            break;
2066
2067
0
        case 6: /*BD32S */
2068
0
            bias = 0;
2069
0
            round = image->scaled_flag? 3 : 0;
2070
0
            clip_hig = 0x7fffffff;
2071
0
            clip_low = -(clip_hig + 1);
2072
0
            break;
2073
2074
0
        case 4: /* BD16F */
2075
2076
0
        case 7: /* BD32F */
2077
0
            bias = 0;
2078
0
            round = image->scaled_flag? 3 : 0;
2079
0
            break;
2080
2081
0
        case 8: /* BD5 */
2082
0
            bias = 16;
2083
0
            round = image->scaled_flag? 3 : 0;
2084
0
            clip_hig = 31;
2085
0
            clip_low = 0;
2086
0
            break;
2087
2088
0
        case 9: /* BD10 */
2089
0
            bias = 512;
2090
0
            round = image->scaled_flag? 3 : 0;
2091
0
            clip_hig = 1023;
2092
0
            clip_low = 0;
2093
0
            break;
2094
2095
0
        case 10: /* BD565 */
2096
0
            bias = 32;
2097
0
            round = image->scaled_flag? 3 : 0;
2098
0
            clip_hig = 31;
2099
0
            clip_low = 0;
2100
0
            break;
2101
2102
0
        case 5: /* Reserved */
2103
2104
0
        default:
2105
0
            fprintf(stderr, "XXXX Don't know how to scale bit depth %d?\n", SOURCE_BITDEPTH(image));
2106
0
            bias = 0;
2107
0
            round = image->scaled_flag? 3 : 0;
2108
0
            clip_low = 0;
2109
0
            clip_hig = 255;
2110
0
            break;
2111
0
    }
2112
2113
0
    DEBUG("scale_and_emit_top: scale=%d, bias=%d, round=%d, shift_bits=%d, clip_low=%d, clip_hig=%d\n",
2114
0
        scale, bias, round, shift_bits, clip_low, clip_hig);
2115
2116
    /* Up 'til this point, the MB contains 4x4 sub-blocks. We are
2117
    now ready for the MB to contain only raster data within, so
2118
    this loop rasterizes all the MBs in this strip. */
2119
0
    for (idx = 0 ; idx < (int) EXTENDED_WIDTH_BLOCKS(image); idx += 1) {
2120
2121
0
        int ch;
2122
0
        int*dp = image->strip[0].up3[idx].data;
2123
0
        unblock_shuffle444(dp);
2124
0
        for (ch = 1 ; ch < image->num_channels ; ch += 1) {
2125
0
            dp = image->strip[ch].up3[idx].data;
2126
0
            switch (image->use_clr_fmt) {
2127
0
                case 1: /* YUV420 */
2128
0
                    unblock_shuffle420(dp);
2129
0
                    break;
2130
0
                case 2: /* YUV422 */
2131
0
                    unblock_shuffle422(dp);
2132
0
                    break;
2133
0
                default:
2134
0
                    unblock_shuffle444(dp);
2135
0
                    break;
2136
0
            }
2137
0
        }
2138
0
    }
2139
2140
0
    for (idx = 0 ; idx < (int) EXTENDED_WIDTH_BLOCKS(image); idx += 1) {
2141
2142
0
        int ch;
2143
#if defined(DETAILED_DEBUG) && 1
2144
        for (ch = 0 ; ch < image->num_channels ; ch += 1) {
2145
            int count = 256;
2146
            if (ch > 0 && image->use_clr_fmt==2/*YUV422*/)
2147
                count = 128;
2148
            if (ch > 0 && image->use_clr_fmt==1/*YUV420*/)
2149
                count = 64;
2150
2151
            DEBUG("image yuv mx=%3d my=%3d ch=%d:", idx, use_my-3, ch);
2152
            int jdx;
2153
            for (jdx = 0 ; jdx < count ; jdx += 1) {
2154
                if (jdx%8 == 0 && jdx != 0)
2155
                    DEBUG("\n%*s", 29, "");
2156
                DEBUG(" %08x", image->strip[ch].up3[idx].data[jdx]);
2157
            }
2158
            DEBUG("\n");
2159
        }
2160
#endif
2161
2162
0
        if(SOURCE_CLR_FMT(image)  == JXR_OCF_YUV420 || SOURCE_CLR_FMT(image) == JXR_OCF_YUV422 ||
2163
0
           SOURCE_CLR_FMT(image)  == JXR_OCF_YUV444 || SOURCE_CLR_FMT(image) == JXR_OCF_CMYKDIRECT)
2164
0
        {
2165
0
            bSkipColorTransform = 1;
2166
0
        }
2167
2168
        /* Perform transform in place, if needed. */
2169
        /* For YCC output, no color transform is needed */
2170
0
        if(!bSkipColorTransform) {
2171
0
            switch (image->use_clr_fmt) {
2172
2173
0
                case 1: /* YUV420 */
2174
0
                    yuv420_to_yuv444(image, use_my, idx);
2175
0
                    yuv444_to_rgb(image, idx);
2176
0
                    break;
2177
2178
0
                case 2: /* YUV422 */
2179
0
                    yuv422_to_yuv444(image, idx);
2180
0
                    yuv444_to_rgb(image, idx);
2181
0
                    break;
2182
2183
0
                case 3: /* YUV444 */
2184
0
                    yuv444_to_rgb(image, idx);
2185
0
                    break;
2186
2187
0
                case 4: /* CMYK */
2188
0
                    yuvk_to_cmyk(image, idx);
2189
0
                    break;
2190
0
            }
2191
0
        } else if (SOURCE_CLR_FMT(image) == JXR_OCF_CMYKDIRECT && image->primary) {
2192
          /* CYMKDirect is a special case. */
2193
0
          yuvk_to_cmykdirect(image, idx);
2194
0
        } else if (SOURCE_CLR_FMT(image) == JXR_OCF_YUV444) {
2195
          /* FIX THOR:
2196
          ** Note that YUV444 can also come in subsampled variants, thus upsampling might be required here.
2197
          */
2198
0
          switch(image->use_clr_fmt) {
2199
0
          case 1: /* YUV420 */
2200
0
            yuv420_to_yuv444(image, use_my, idx);
2201
0
            break;
2202
0
          case 2: /* YUV422 */
2203
0
            yuv422_to_yuv444(image, idx);
2204
0
            break;
2205
0
          }
2206
0
        }
2207
2208
        /* The strip data is now in the output color space. */
2209
2210
        /* AddBias and ComputeScaling */
2211
0
        if (image->use_clr_fmt == JXR_OCF_CMYK &&
2212
0
            SOURCE_CLR_FMT(image) != JXR_OCF_CMYKDIRECT/*CMYK*/) {
2213
          /* The CMYK format has a different and unique set
2214
             of bias/rounding calculations. Treat it as a
2215
             special case. And treat the K plane even more
2216
             special. */
2217
0
          shift_and_clip_CMYK(image,idx,bias,shift_bits,scale,round,clip_low,clip_hig);
2218
0
        } else if (SOURCE_BITDEPTH(image) == JXR_BD565) {
2219
          /*
2220
          ** BD565 has two irregularities: special depth of green, and the b-r swap
2221
          */
2222
0
          assert(image->num_channels == 3 || image->num_channels == 1);
2223
0
          if (image->num_channels == 1) {
2224
0
            shift_and_clip_regular(image,idx,bias,shift_bits,scale,round,0,63);
2225
0
          } else {
2226
0
            shift_and_clip_BD565(image,idx,bias,scale,round);
2227
0
          }
2228
0
        } else if (!bSkipColorTransform &&
2229
0
                   (SOURCE_BITDEPTH(image) == JXR_BD5 || SOURCE_BITDEPTH(image) == JXR_BD10)) {
2230
          /*
2231
          ** BD555 and BD101010 have one irregularity, namely the b-r swap
2232
          */
2233
0
          assert(image->num_channels == 3 || image->num_channels == 1);
2234
0
          if (image->num_channels == 1) {
2235
0
            shift_and_clip_regular(image,idx,bias,shift_bits,scale,round,clip_low,clip_hig);
2236
0
          } else {
2237
0
            shift_and_clip_BDxxx(image,idx,bias,shift_bits,scale,round,clip_low,clip_hig);
2238
0
          }
2239
0
        } else if (SOURCE_BITDEPTH(image) == JXR_BD16F || SOURCE_BITDEPTH(image) == JXR_BD32F) {
2240
          /*
2241
          ** the wide cases, floating point
2242
          */
2243
0
          shift_and_clip_FLOAT(image,idx,scale,round);
2244
0
        } else if (SOURCE_CLR_FMT(image) == JXR_OCF_RGBE) {
2245
          /*
2246
          ** The RGBE case
2247
          */
2248
0
          shift_and_clip_RGBE(image,idx,scale,round,buffer);
2249
0
        } else {
2250
          /*
2251
          ** the regular case
2252
          */
2253
0
          shift_and_clip_regular(image,idx,bias,shift_bits,scale,round,clip_low,clip_hig);
2254
0
        }
2255
2256
0
         if ( image->primary == 1 ) {  /* alpha channel output is combined with primary channel */
2257
0
            int px;
2258
0
            int channels = image->num_channels;
2259
2260
0
            if(!bSkipColorTransform) { /* Interleave channels in buffer */
2261
0
                if (ALPHACHANNEL_FLAG(image))
2262
0
                  channels ++;
2263
2264
0
                if (SOURCE_CLR_FMT(image) != JXR_OCF_RGBE) {
2265
                  /*RGBE is a special case that is already taken care of */
2266
0
                  for (px = 0 ; px < 256 ; px += 1)
2267
0
                    for (ch = 0 ; ch < image->num_channels ; ch += 1)
2268
0
                      buffer[channels*px + ch] = image->strip[ch].up3[idx].data[px];
2269
0
                }
2270
2271
0
                if (ALPHACHANNEL_FLAG(image))
2272
0
                    for (px = 0 ; px < 256 ; px += 1)
2273
0
                        buffer[channels*px + image->num_channels] = image->alpha->strip[0].up3[idx].data[px];
2274
0
            } else {
2275
0
              int size =  256*sizeof(uint32_t);
2276
0
              int i = 0;
2277
0
              for(i = 0; i < image->num_channels; i ++) {
2278
0
                memcpy(((uint8_t *)buffer + i*size), image->strip[i].up3[idx].data, size);
2279
0
              }
2280
0
              if(ALPHACHANNEL_FLAG(image))
2281
0
                memcpy(((uint8_t *)buffer) + image->num_channels*size, image->alpha->strip[0].up3[idx].data, size);
2282
0
            }
2283
2284
0
            _jxr_send_mb_to_output(image, idx, use_my-3, buffer);
2285
2286
            /* thor: Added April 2 2010: Indicate by a flag that some output has been generated */
2287
0
            image->output_sent = 1;
2288
0
        }
2289
0
    }
2290
0
}
2291
2292
/*
2293
* The tile_row_buffer holds flushed mb data in image raster order,
2294
* along with other per-mb data. This is in support of SPATIAL processing.
2295
*/
2296
static void rflush_to_tile_buffer(jxr_image_t image, int tx, int my)
2297
0
{
2298
0
    int format_scale = 256;
2299
0
    int mx;
2300
0
    DEBUG("rflush_mb_strip: rflush_to_tile_buffer tx=%d, my=%d\n", tx, my);
2301
2302
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
2303
0
        format_scale = 16 + 8*15;
2304
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
2305
0
        format_scale = 16 + 4*15;
2306
0
    }
2307
2308
0
    for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
2309
0
        int off;
2310
0
        int ch;
2311
0
        DEBUG("rflush_mb_strip: rflush_to_tile_buffer tx=%d, mx=%d, CUR=0x%08x UP1=0x%08x, UP2=0x%08x, UP3=0x%08x, LP_QUANT=%d\n",
2312
0
            tx, mx, MACROBLK_CUR(image,0,tx,mx).data[0],
2313
0
            MACROBLK_UP1(image,0,tx,mx).data[0],
2314
0
            MACROBLK_UP2(image,0,tx,mx).data[0],
2315
0
            MACROBLK_UP3(image,0,tx,mx).data[0],
2316
0
            MACROBLK_CUR_LP_QUANT(image,0,tx,mx));
2317
2318
0
        off = my * EXTENDED_WIDTH_BLOCKS(image) + image->tile_column_position[tx] + mx;
2319
0
        for (ch = 0; ch < image->num_channels; ch += 1) {
2320
0
            int count;
2321
0
            int idx;
2322
0
            struct macroblock_s*mb = image->mb_row_buffer[ch] + off;
2323
0
            mb->lp_quant = MACROBLK_CUR_LP_QUANT(image,ch,tx,mx);
2324
0
            mb->hp_quant = MACROBLK_CUR(image,ch,tx,mx).hp_quant;
2325
0
            count = (ch==0)? 256 : format_scale;
2326
0
            for (idx = 0 ; idx < count ; idx += 1)
2327
0
                mb->data[idx] = MACROBLK_CUR(image,ch,tx,mx).data[idx];
2328
0
        }
2329
0
    }
2330
0
}
2331
2332
/*
2333
* Recover a strip of data from all but the last column of data. Skip
2334
* the last column because this function is called while the last
2335
* column is being processed.
2336
*/
2337
static void rflush_collect_mb_strip_data(jxr_image_t image, int my)
2338
0
{
2339
0
    int format_scale = 256;
2340
0
    int tx;
2341
0
    DEBUG("rflush_mb_strip: rflush_collect_mb_strip_data my=%d\n", my);
2342
2343
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
2344
0
        format_scale = 16 + 8*15;
2345
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
2346
0
        format_scale = 16 + 4*15;
2347
0
    }
2348
2349
0
    for (tx = 0; tx < (int) image->tile_columns-1 ; tx += 1) {
2350
0
        int mx;
2351
0
        for (mx = 0; mx < (int) image->tile_column_width[tx]; mx += 1) {
2352
0
            int off = my * EXTENDED_WIDTH_BLOCKS(image) + image->tile_column_position[tx] + mx;
2353
0
            int ch;
2354
0
            for (ch = 0; ch < image->num_channels; ch += 1) {
2355
0
                struct macroblock_s*mb = image->mb_row_buffer[ch] + off;
2356
0
                int count;
2357
0
                int idx;
2358
0
                MACROBLK_CUR_LP_QUANT(image,ch,tx,mx) = mb->lp_quant;
2359
0
                MACROBLK_CUR(image,ch,tx,mx).hp_quant = mb->hp_quant;
2360
0
                count = (ch==0)? 256 : format_scale;
2361
0
                for (idx = 0 ; idx < count; idx += 1)
2362
0
                    MACROBLK_CUR(image,ch,tx,mx).data[idx] = mb->data[idx];
2363
0
            }
2364
0
            DEBUG("rflush_mb_strip: rflush_collect_mb_strip_data tx=%d, mx=%d, CUR=0x%08x UP1=0x%08x, UP2=0x%08x, UP3=0x%08x lp_quant=%d\n",
2365
0
                tx, mx, MACROBLK_CUR(image,0,tx,mx).data[0],
2366
0
                MACROBLK_UP1(image,0,tx,mx).data[0],
2367
0
                MACROBLK_UP2(image,0,tx,mx).data[0],
2368
0
                MACROBLK_UP3(image,0,tx,mx).data[0],
2369
0
                MACROBLK_CUR_LP_QUANT(image,0,tx,mx));
2370
0
        }
2371
0
    }
2372
0
}
2373
2374
/*
2375
* The save_ and recover_context functions save the 3 strips of data
2376
* currently in the strip buffer. This is used at the end of a tile
2377
* row and beginning of the next tile row to save context while
2378
* columns of tiles are collected, and restore it when processing the
2379
* last tile column.
2380
*/
2381
static void rflush_save_context(jxr_image_t image)
2382
0
{
2383
0
    int format_scale = 256;
2384
0
    int tx;
2385
0
    DEBUG("rflush_mb_strip: rflush_save_context\n");
2386
2387
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
2388
0
        format_scale = 16 + 8*15;
2389
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
2390
0
        format_scale = 16 + 4*15;
2391
0
    }
2392
2393
0
    for (tx = 0; tx < (int) image->tile_columns ; tx += 1) {
2394
0
        int mx;
2395
0
        for (mx = 0; mx < (int) image->tile_column_width[tx]; mx += 1) {
2396
0
            int off0 = image->tile_column_position[tx] + mx;
2397
0
            int off1 = off0 + EXTENDED_WIDTH_BLOCKS(image);
2398
0
            int off2 = off1 + EXTENDED_WIDTH_BLOCKS(image);
2399
0
            int off3 = off2 + EXTENDED_WIDTH_BLOCKS(image);
2400
0
            int ch;
2401
0
            DEBUG("rflush_mb_strip: rflush_save_context tx=%d, mx=%d, CUR=0x%08x UP1=0x%08x, UP2=0x%08x, UP3=0x%08x\n",
2402
0
                tx, mx, MACROBLK_CUR(image,0,tx,mx).data[0],
2403
0
                MACROBLK_UP1(image,0,tx,mx).data[0],
2404
0
                MACROBLK_UP2(image,0,tx,mx).data[0],
2405
0
                MACROBLK_UP3(image,0,tx,mx).data[0]);
2406
0
            for (ch = 0; ch < image->num_channels; ch += 1) {
2407
0
                int count;
2408
0
                int idx;
2409
2410
0
                image->mb_row_context[ch][off0].lp_quant = MACROBLK_CUR_LP_QUANT(image,ch,tx,mx);
2411
0
                image->mb_row_context[ch][off1].lp_quant = MACROBLK_UP1_LP_QUANT(image,ch,tx,mx);
2412
0
                image->mb_row_context[ch][off2].lp_quant = MACROBLK_UP2(image,ch,tx,mx).lp_quant;
2413
0
                image->mb_row_context[ch][off3].lp_quant = MACROBLK_UP3(image,ch,tx,mx).lp_quant;
2414
0
                image->mb_row_context[ch][off0].hp_quant = MACROBLK_CUR(image,ch,tx,mx).hp_quant;
2415
0
                image->mb_row_context[ch][off1].hp_quant = MACROBLK_UP1(image,ch,tx,mx).hp_quant;
2416
0
                image->mb_row_context[ch][off2].hp_quant = MACROBLK_UP2(image,ch,tx,mx).hp_quant;
2417
0
                image->mb_row_context[ch][off3].hp_quant = MACROBLK_UP3(image,ch,tx,mx).hp_quant;
2418
0
                count = (ch==0)? 256 : format_scale;
2419
0
                for (idx = 0 ; idx < count; idx += 1)
2420
0
                    image->mb_row_context[ch][off0].data[idx] = MACROBLK_CUR(image,ch,tx,mx).data[idx];
2421
0
                for (idx = 0 ; idx < count; idx += 1)
2422
0
                    image->mb_row_context[ch][off1].data[idx] = MACROBLK_UP1(image,ch,tx,mx).data[idx];
2423
0
                for (idx = 0 ; idx < count; idx += 1)
2424
0
                    image->mb_row_context[ch][off2].data[idx] = MACROBLK_UP2(image,ch,tx,mx).data[idx];
2425
0
                for (idx = 0 ; idx < count; idx += 1)
2426
0
                    image->mb_row_context[ch][off3].data[idx] = MACROBLK_UP3(image,ch,tx,mx).data[idx];
2427
0
            }
2428
0
        }
2429
0
    }
2430
0
}
2431
2432
static void rflush_recover_context(jxr_image_t image)
2433
0
{
2434
2435
0
    int format_scale = 256;
2436
0
    int tx;
2437
0
    DEBUG("rflush_mb_strip: recover contex\n");
2438
2439
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
2440
0
        format_scale = 16 + 8*15;
2441
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
2442
0
        format_scale = 16 + 4*15;
2443
0
    }
2444
2445
0
    for (tx = 0; tx < (int) image->tile_columns ; tx += 1) {
2446
0
        int mx;
2447
0
        for (mx = 0; mx < (int) image->tile_column_width[tx]; mx += 1) {
2448
0
            int off0 = image->tile_column_position[tx] + mx;
2449
0
            int off1 = off0 + EXTENDED_WIDTH_BLOCKS(image);
2450
0
            int off2 = off1 + EXTENDED_WIDTH_BLOCKS(image);
2451
0
            int off3 = off2 + EXTENDED_WIDTH_BLOCKS(image);
2452
0
            int ch;
2453
0
            for (ch = 0; ch < image->num_channels; ch += 1) {
2454
0
                int count;
2455
0
                int idx;
2456
0
                MACROBLK_CUR_LP_QUANT(image,ch,tx,mx) = image->mb_row_context[ch][off0].lp_quant;
2457
0
                MACROBLK_UP1_LP_QUANT(image,ch,tx,mx) = image->mb_row_context[ch][off1].lp_quant;
2458
0
                MACROBLK_UP2(image,ch,tx,mx).lp_quant = image->mb_row_context[ch][off2].lp_quant;
2459
0
                MACROBLK_UP3(image,ch,tx,mx).lp_quant = image->mb_row_context[ch][off3].lp_quant;
2460
0
                MACROBLK_CUR(image,ch,tx,mx).hp_quant = image->mb_row_context[ch][off0].hp_quant;
2461
0
                MACROBLK_UP1(image,ch,tx,mx).hp_quant = image->mb_row_context[ch][off1].hp_quant;
2462
0
                MACROBLK_UP2(image,ch,tx,mx).hp_quant = image->mb_row_context[ch][off2].hp_quant;
2463
0
                MACROBLK_UP3(image,ch,tx,mx).hp_quant = image->mb_row_context[ch][off3].hp_quant;
2464
0
                count = (ch==0)? 256 : format_scale;
2465
0
                for (idx = 0 ; idx < count; idx += 1)
2466
0
                    MACROBLK_CUR(image,ch,tx,mx).data[idx] = image->mb_row_context[ch][off0].data[idx];
2467
0
                for (idx = 0 ; idx < count; idx += 1)
2468
0
                    MACROBLK_UP1(image,ch,tx,mx).data[idx] = image->mb_row_context[ch][off1].data[idx];
2469
0
                for (idx = 0 ; idx < count; idx += 1)
2470
0
                    MACROBLK_UP2(image,ch,tx,mx).data[idx] = image->mb_row_context[ch][off2].data[idx];
2471
0
                for (idx = 0 ; idx < count; idx += 1)
2472
0
                    MACROBLK_UP3(image,ch,tx,mx).data[idx] = image->mb_row_context[ch][off3].data[idx];
2473
0
            }
2474
0
        }
2475
0
    }
2476
0
}
2477
2478
2479
/*
2480
* When the parser calls this function, the current strip is done
2481
* being parsed, so it no longer needs the previous strip. Complete
2482
* the processing of the previous ("up") strip and arrange for it to
2483
* be delivered to the applications. Then shuffle the current strip to
2484
* the "up" position for the next round.
2485
*
2486
* cur_my is the number of the current line. If this is -1, then there
2487
* are no lines complete yet and this function is being called to get
2488
* things started.
2489
*/
2490
void _jxr_rflush_mb_strip(jxr_image_t image, int tx, int ty, int my)
2491
0
{
2492
    /* This is the position within the image of the current
2493
    line. It accounts for the current tile row. */
2494
0
    const int use_my = my + (ty>=0? image->tile_row_position[ty] : 0) - 1;
2495
2496
0
    DEBUG("rflush_mb_strip: cur_my=%d, tile-x/y=%d/%d, my=%d, use_my=%d\n", image->cur_my, tx, ty, my, use_my);
2497
2498
0
    if (image->tile_columns > 1 && tx >= 0) {
2499
0
        if (tx+1 < (int) image->tile_columns) {
2500
            /* We're actually working on a tile, and this is
2501
            not the last tile in the row. Deliver the data
2502
            to the correct tile buffer and return. */
2503
2504
0
            if (my == 0 && image->cur_my >= 0) {
2505
                /* starting a new tile, dump previous */
2506
2507
0
                if (tx == 0 && ty > 0) {
2508
                    /* First column of a row */
2509
                    /* Complete last line of previous row */
2510
0
                    rflush_collect_mb_strip_data(image, image->cur_my);
2511
                    /* Save previous strip context */
2512
0
                    rflush_save_context(image);
2513
                    /* Flush last column of previous row. */
2514
0
                    rflush_to_tile_buffer(image, image->tile_columns-1, image->cur_my);
2515
0
                } else if (tx > 0) {
2516
                    /* Column within a row, dump previous column */
2517
0
                    rflush_to_tile_buffer(image, tx-1, image->cur_my);
2518
0
                }
2519
2520
0
            } else if (image->cur_my >= 0) {
2521
0
                rflush_to_tile_buffer(image, tx, image->cur_my);
2522
0
            }
2523
0
            image->cur_my = my;
2524
0
            _jxr_r_rotate_mb_strip(image);
2525
0
            return;
2526
2527
0
        } else {
2528
            /* We are tiling, and this is the last tile of the
2529
            row, so collect rows from the left tiles to
2530
            finish the row, and proceed to processing. */
2531
0
            if (my == 0) {
2532
                /* Starting last tile of row */
2533
                /* Flush end of previous tile */
2534
0
                rflush_to_tile_buffer(image, tx-1, image->cur_my);
2535
0
                image->cur_my = -1;
2536
                /* Recover previous strip context */
2537
0
                if (ty > 0) {
2538
0
                    rflush_recover_context(image);
2539
0
                }
2540
0
            } else if (my <= (int) image->tile_row_height[ty]) {
2541
0
                rflush_collect_mb_strip_data(image, image->cur_my);
2542
0
            }
2543
0
        }
2544
0
    }
2545
2546
2547
0
    if (use_my >= 1) {
2548
0
        int ch;
2549
2550
        /* Dequantize the PREVIOUS strip of macroblocks DC and LP. */
2551
2552
        /* Reverse transform the DC/LP to 16 DC values. */
2553
2554
0
        for (ch = 0 ; ch < image->num_channels ; ch += 1)
2555
0
            IPCT_level1_up1(image, use_my, ch);
2556
2557
0
        if (use_my >= 2) {
2558
0
            if (OVERLAP_INFO(image) >= 2)
2559
0
                for (ch = 0 ; ch < image->num_channels ; ch += 1)
2560
0
                    overlap_level1_up2(image, use_my, ch);
2561
2562
            /* Do the second level IPCT transform to include HP values. */
2563
0
            for (ch = 0 ; ch < image->num_channels ; ch += 1)
2564
0
                IPCT_level2_up2(image,use_my, ch);
2565
2566
0
            if (use_my >= 3) {
2567
2568
                /* Do the second level post filter */
2569
0
                if (OVERLAP_INFO(image) >= 1)
2570
0
                    for (ch = 0 ; ch < image->num_channels ; ch += 1)
2571
0
                        overlap_level2_up3(image, use_my, ch);
2572
2573
                /* The reverse transformation is complete for the
2574
                PREVIOUS strip, so perform the "Output Formatting"
2575
                and deliver the data for the application. */
2576
2577
0
                scale_and_emit_top(image, tx, use_my);
2578
0
            }
2579
0
        }
2580
2581
        /* read lwf test flag into image container */
2582
0
        if (image->lwf_test == 0)
2583
0
            image->lwf_test = _jxr_read_lwf_test_flag();
2584
2585
0
    }
2586
2587
    /* Now completely done with strip_up. Rotate the storage to
2588
    strip_down. */
2589
0
    image->cur_my = my;
2590
2591
0
    _jxr_r_rotate_mb_strip(image);
2592
0
}
2593
2594
/*
2595
* The input to this function is 256 samples arranged like this:
2596
*
2597
* DC..DC (16 DC values) HP..HP (240 HP values)
2598
*
2599
* Shuffle the values so that there is 1 DC, then 15 HP, and so on 16
2600
* times. This prepares the array for 16 calls to the 4x4IPCT transform.
2601
*/
2602
static void dclphp_shuffle(int*data, int dclp_count)
2603
0
{
2604
0
    int tmp[256];
2605
0
    int dc, hp, dst;
2606
0
    assert(dclp_count <= 16);
2607
2608
0
    for (dc=0, hp=16, dst=0; dc<dclp_count ; ) {
2609
0
        int idx;
2610
0
        tmp[dst++] = data[dc++];
2611
0
        for (idx = 0 ; idx < 15 ; idx += 1)
2612
0
            tmp[dst++] = data[hp++];
2613
0
    }
2614
2615
0
    assert(dst == 16*dclp_count);
2616
0
    assert(dc == dclp_count);
2617
0
    assert(hp == 16+15*dclp_count);
2618
2619
0
    for (dst = 0 ; dst<256 ; dst+=1)
2620
0
        data[dst] = tmp[dst];
2621
0
}
2622
2623
/*
2624
* The input to this function is 256 intensities arranged as blocks,
2625
* with each 4x4 block in raster order is together, i.e.
2626
*
2627
* 00..0011..1122..22...
2628
*
2629
* It reorders the values into a raster order that is not blocked:
2630
*
2631
* 0000111122223333
2632
* 0000111122223333
2633
* 0000111122223333, etc.
2634
*/
2635
static void unblock_shuffle444(int*data)
2636
0
{
2637
0
    int tmp[256];
2638
2639
0
    int idx;
2640
0
    for (idx = 0 ; idx < 256 ; idx += 4) {
2641
0
        int blk = idx/16;
2642
0
        int mbx = blk%4;
2643
0
        int mby = blk/4;
2644
0
        int pix = idx%16;
2645
0
        int py = pix/4;
2646
2647
0
        int ptr = 16*4*mby + 4*mbx + 16*py;
2648
0
        tmp[ptr+0] = data[idx+0];
2649
0
        tmp[ptr+1] = data[idx+1];
2650
0
        tmp[ptr+2] = data[idx+2];
2651
0
        tmp[ptr+3] = data[idx+3];
2652
0
    }
2653
2654
0
    for (idx = 0 ; idx < 256 ; idx += 1)
2655
0
        data[idx] = tmp[idx];
2656
0
}
2657
2658
/*
2659
* 0 1 2 3 16 17 18 19
2660
* 4 5 6 7 20 21 22 23
2661
* 8 9 10 11 24 25 26 27
2662
* 12 13 14 15 28 29 30 31
2663
* 32 33 34 35 48 49 50 51
2664
* 36 37 38 39 52 53 54 55
2665
* 40 41 42 43 56 57 58 59
2666
* 44 45 46 47 60 61 62 63 ...
2667
*/
2668
static void unblock_shuffle422(int*data)
2669
0
{
2670
0
    int tmp[128];
2671
2672
0
    int idx;
2673
0
    for (idx = 0 ; idx < 128 ; idx += 4) {
2674
0
        int blk = idx/16;
2675
0
        int mbx = blk%2;
2676
0
        int mby = blk/2;
2677
0
        int pix = idx%16;
2678
0
        int py = pix/4;
2679
2680
0
        int ptr = 16*2*mby + 4*mbx + 8*py;
2681
0
        tmp[ptr+0] = data[idx+0];
2682
0
        tmp[ptr+1] = data[idx+1];
2683
0
        tmp[ptr+2] = data[idx+2];
2684
0
        tmp[ptr+3] = data[idx+3];
2685
0
    }
2686
2687
0
    for (idx = 0 ; idx < 128 ; idx += 1)
2688
0
        data[idx] = tmp[idx];
2689
0
}
2690
2691
/*
2692
* 0 1 2 3 16 17 18 19
2693
* 4 5 6 7 20 21 22 23
2694
* 8 9 10 11 24 25 26 27
2695
* 12 13 14 15 28 29 30 31
2696
* 32 33 34 35 48 49 50 51
2697
* 36 37 38 39 52 53 54 55
2698
* 40 41 42 43 56 57 58 59
2699
* 44 45 46 47 60 61 62 63
2700
*/
2701
static void unblock_shuffle420(int*data)
2702
0
{
2703
0
    int tmp[64];
2704
2705
0
    int idx;
2706
0
    for (idx = 0 ; idx < 64 ; idx += 4) {
2707
0
        int blk = idx/16;
2708
0
        int mbx = blk%2;
2709
0
        int mby = blk/2;
2710
0
        int pix = idx%16;
2711
0
        int py = pix/4;
2712
2713
0
        int ptr = 16*2*mby + 4*mbx + 8*py;
2714
0
        tmp[ptr+0] = data[idx+0];
2715
0
        tmp[ptr+1] = data[idx+1];
2716
0
        tmp[ptr+2] = data[idx+2];
2717
0
        tmp[ptr+3] = data[idx+3];
2718
0
    }
2719
2720
0
    for (idx = 0 ; idx < 64 ; idx += 1)
2721
0
        data[idx] = tmp[idx];
2722
0
}
2723
2724
void _jxr_r_rotate_mb_strip(jxr_image_t image)
2725
0
{
2726
0
    if(image->primary) {
2727
0
        int ch;
2728
2729
0
        for (ch = 0 ; ch < image->num_channels ; ch += 1) {
2730
0
            struct macroblock_s*tmp = image->strip[ch].up3;
2731
0
            image->strip[ch].up3 = image->strip[ch].up2;
2732
0
            image->strip[ch].up2 = image->strip[ch].up1;
2733
0
            image->strip[ch].up1 = image->strip[ch].cur;
2734
0
            image->strip[ch].cur = tmp;
2735
0
        }
2736
2737
0
        _jxr_clear_strip_cur(image);
2738
2739
0
        if (ALPHACHANNEL_FLAG(image)) {
2740
0
            struct macroblock_s*tmp = image->alpha->strip[0].up3;
2741
0
            image->alpha->strip[0].up3 = image->alpha->strip[0].up2;
2742
0
            image->alpha->strip[0].up2 = image->alpha->strip[0].up1;
2743
0
            image->alpha->strip[0].up1 = image->alpha->strip[0].cur;
2744
0
            image->alpha->strip[0].cur = tmp;
2745
0
            _jxr_clear_strip_cur(image->alpha);
2746
0
        }
2747
0
    }
2748
0
}
2749
2750
2751
/*
2752
* $Log: r_strip.c,v $
2753
* Revision 1.18  2011-11-19 20:52:34  thor
2754
* Fixed decoding of YUV422 in 10bpp, fixed 10bpp tiff reading and writing.
2755
*
2756
* Revision 1.17  2011-11-09 15:53:14  thor
2757
* Fixed the bugs reported by Microsoft. Rewrote the output color
2758
* transformation completely.
2759
*
2760
* Revision 1.16  2011-11-08 20:17:29  thor
2761
* Merged a couple of fixes from the JNB.
2762
*
2763
* Revision 1.15  2011-04-28 08:45:43  thor
2764
* Fixed compiler warnings, ported to gcc 4.4, removed obsolete files.
2765
*
2766
* Revision 1.14  2011-03-08 17:42:48  thor
2767
* Forgot the downsampling for an output color format of YUV444 on encoding.
2768
*
2769
* Revision 1.13  2011-03-08 17:30:57  thor
2770
* Upsampling from YUV42x -> YUV444 does not work.
2771
*
2772
* Revision 1.11  2010-08-31 10:10:44  thor
2773
* Fixed the channel order in CMYKDirect.
2774
*
2775
* Revision 1.10  2010-05-13 16:30:03  thor
2776
* Added options to set the chroma centering. Fixed writing of BGR565.
2777
* Made the "-p" output option nicer.
2778
*
2779
* Revision 1.9  2010-05-01 11:16:08  thor
2780
* Fixed the tiff tag order. Added spatial/line mode.
2781
*
2782
* Revision 1.8  2010-03-31 07:50:59  thor
2783
* Replaced by the latest MS version.
2784
*
2785
* Revision 1.53 2009/05/29 12:00:00 microsoft
2786
* Reference Software v1.6 updates.
2787
*
2788
* Revision 1.52 2009/04/13 12:00:00 microsoft
2789
* Reference Software v1.5 updates.
2790
*
2791
* Revision 1.51 2008/03/24 18:06:56 steve
2792
* Imrpove DEBUG messages around quantization.
2793
*
2794
* Revision 1.50 2008/03/20 22:38:53 steve
2795
* Use MB HPQP instead of first HPQP in decode.
2796
*
2797
* Revision 1.49 2008/03/18 21:09:11 steve
2798
* Fix distributed color prediction.
2799
*
2800
* Revision 1.48 2008/03/17 23:48:12 steve
2801
* Bias and Scaling for CMYK
2802
*
2803
* Revision 1.47 2008/03/17 21:48:56 steve
2804
* CMYK decode support
2805
*
2806
* Revision 1.46 2008/03/14 17:08:51 gus
2807
* *** empty log message ***
2808
*
2809
* Revision 1.45 2008/03/13 17:49:31 steve
2810
* Fix problem with YUV422 CBP prediction for UV planes
2811
*
2812
* Add support for YUV420 encoding.
2813
*
2814
* Revision 1.44 2008/03/11 22:12:49 steve
2815
* Encode YUV422 through DC.
2816
*
2817
* Revision 1.43 2008/03/05 06:58:10 gus
2818
* *** empty log message ***
2819
*
2820
* Revision 1.42 2008/03/03 23:33:53 steve
2821
* Implement SHIFT_BITS functionality.
2822
*
2823
* Revision 1.41 2008/03/02 18:35:27 steve
2824
* Add support for BD16
2825
*
2826
* Revision 1.40 2008/02/26 23:52:44 steve
2827
* Remove ident for MS compilers.
2828
*
2829
* Revision 1.39 2008/02/01 22:49:53 steve
2830
* Handle compress of YUV444 color DCONLY
2831
*
2832
* Revision 1.38 2008/01/08 23:23:18 steve
2833
* Clean up some DEBUG messages.
2834
*
2835
* Revision 1.37 2008/01/04 17:07:35 steve
2836
* API interface for setting QP values.
2837
*
2838
* Revision 1.36 2007/11/26 01:47:15 steve
2839
* Add copyright notices per MS request.
2840
*
2841
* Revision 1.35 2007/11/22 19:02:05 steve
2842
* More fixes of color plane buffer sizes.
2843
*
2844
* Revision 1.34 2007/11/22 02:51:04 steve
2845
* Fix YUV422 strip save byte count - buffer overrun
2846
*
2847
* Revision 1.33 2007/11/21 23:26:14 steve
2848
* make all strip buffers store MB data.
2849
*
2850
* Revision 1.32 2007/11/21 00:34:30 steve
2851
* Rework spatial mode tile macroblock shuffling.
2852
*
2853
* Revision 1.31 2007/11/20 17:08:02 steve
2854
* Fix SPATIAL processing of QUANT values for color.
2855
*
2856
* Revision 1.30 2007/11/16 21:33:48 steve
2857
* Store MB Quant, not qp_index.
2858
*
2859
* Revision 1.29 2007/11/16 20:03:57 steve
2860
* Store MB Quant, not qp_index.
2861
*
2862
* Revision 1.28 2007/11/12 23:21:55 steve
2863
* Infrastructure for frequency mode ordering.
2864
*
2865
* Revision 1.27 2007/11/09 01:18:58 steve
2866
* Stub strip input processing.
2867
*
2868
* Revision 1.26 2007/11/06 21:45:04 steve
2869
* Fix MB of previous tile in row.
2870
*
2871
* Revision 1.25 2007/11/06 01:39:22 steve
2872
* Do not collect strip data for pad strips.
2873
*
2874
* Revision 1.24 2007/11/05 02:01:12 steve
2875
* Add support for mixed row/column tiles.
2876
*
2877
* Revision 1.23 2007/11/02 21:06:07 steve
2878
* Filtering when tile rows are present.
2879
*
2880
* Revision 1.22 2007/11/02 00:19:06 steve
2881
* Fix Multiple rows of tiles strip flush.
2882
*
2883
* Revision 1.21 2007/11/01 21:09:40 steve
2884
* Multiple rows of tiles.
2885
*
2886
* Revision 1.20 2007/10/30 21:32:46 steve
2887
* Support for multiple tile columns.
2888
*
2889
* Revision 1.19 2007/10/23 00:34:12 steve
2890
* Level1 filtering for YUV422 and YUV420
2891
*
2892
* Revision 1.18 2007/10/22 22:33:12 steve
2893
* Level2 filtering for YUV422
2894
*
2895
* Revision 1.17 2007/10/22 21:52:37 steve
2896
* Level2 filtering for YUV420
2897
*
2898
* Revision 1.16 2007/10/19 22:07:36 steve
2899
* Clean up YUV420 to YUV444 conversion corner cases.
2900
*
2901
* Revision 1.15 2007/10/19 20:48:53 steve
2902
* Convert YUV420 to YUV444 works.
2903
*
2904
* Revision 1.14 2007/10/17 23:43:20 steve
2905
* Add support for YUV420
2906
*
2907
* Revision 1.13 2007/10/01 20:39:34 steve
2908
* Add support for YUV422 LP bands.
2909
*
2910
* Revision 1.12 2007/09/20 18:04:11 steve
2911
* support render of YUV422 images.
2912
*
2913
* Revision 1.11 2007/09/12 01:10:22 steve
2914
* Fix rounding/floor/ceil of YUV to RGB transform.
2915
*
2916
* Revision 1.10 2007/09/11 00:40:06 steve
2917
* Fix rendering of chroma to add the missing *2.
2918
* Fix handling of the chroma LP samples
2919
* Parse some of the HP CBP data in chroma.
2920
*
2921
* Revision 1.9 2007/09/10 23:02:48 steve
2922
* Scale chroma channels?
2923
*
2924
* Revision 1.8 2007/09/08 01:01:44 steve
2925
* YUV444 color parses properly.
2926
*
2927
* Revision 1.7 2007/09/04 19:10:46 steve
2928
* Finish level1 overlap filtering.
2929
*
2930
* Revision 1.6 2007/08/15 01:54:11 steve
2931
* Add level2 filter to decoder.
2932
*
2933
* Revision 1.5 2007/08/13 22:55:12 steve
2934
* Cleanup rflush_md_strip function.
2935
*
2936
* Revision 1.4 2007/08/02 22:48:27 steve
2937
* Add missing clip of calculated values.
2938
*
2939
* Revision 1.3 2007/07/21 00:25:48 steve
2940
* snapshot 2007 07 20
2941
*
2942
* Revision 1.2 2007/07/11 00:53:36 steve
2943
* HP adaptation and precition corrections.
2944
*
2945
* Revision 1.1 2007/06/28 20:03:11 steve
2946
* LP processing seems to be OK now.
2947
*
2948
*/
2949