Coverage Report

Created: 2026-04-01 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/jpegxr/r_tile_frequency.c
Line
Count
Source
1
/*************************************************************************
2
*
3
* This software module was originally contributed by Microsoft
4
* Corporation in the course of development of the
5
* ITU-T T.832 | ISO/IEC 29199-2 ("JPEG XR") format standard for
6
* reference purposes and its performance may not have been optimized.
7
*
8
* This software module is an implementation of one or more
9
* tools as specified by the JPEG XR standard.
10
*
11
* ITU/ISO/IEC give You a royalty-free, worldwide, non-exclusive
12
* copyright license to copy, distribute, and make derivative works
13
* of this software module or modifications thereof for use in
14
* products claiming conformance to the JPEG XR standard as
15
* specified by ITU-T T.832 | ISO/IEC 29199-2.
16
*
17
* ITU/ISO/IEC give users the same free license to this software
18
* module or modifications thereof for research purposes and further
19
* ITU/ISO/IEC standardization.
20
*
21
* Those intending to use this software module in products are advised
22
* that its use may infringe existing patents. ITU/ISO/IEC have no
23
* liability for use of this software module or modifications thereof.
24
*
25
* Copyright is not released for products that do not conform to
26
* to the JPEG XR standard as specified by ITU-T T.832 |
27
* ISO/IEC 29199-2.
28
*
29
* Microsoft Corporation retains full right to modify and use the code
30
* for its own purpose, to assign or donate the code to a third party,
31
* and to inhibit third parties from using the code for products that
32
* do not conform to the JPEG XR standard as specified by ITU-T T.832 |
33
* ISO/IEC 29199-2.
34
*
35
* This copyright notice must be included in all copies or derivative
36
* works.
37
*
38
* Copyright (c) ITU-T/ISO/IEC 2008, 2009.
39
***********************************************************************/
40
41
#ifdef _MSC_VER
42
#pragma comment (user,"$Id: r_tile_frequency.c,v 1.14 2008/03/18 21:34:04 steve Exp $")
43
#else
44
#ident "$Id: r_tile_frequency.c,v 1.14 2008/03/18 21:34:04 steve Exp $"
45
#endif
46
47
# include "jxr_priv.h"
48
# include <assert.h>
49
50
static void backup_dc_strip(jxr_image_t image, int tx, int ty, int my);
51
static void backup_dclp_strip(jxr_image_t image, int tx, int ty, int my);
52
static void backup_hp_strip(jxr_image_t image, int tx, int ty, int my);
53
static void recover_dc_strip(jxr_image_t image, int tx, int ty, int my);
54
static void recover_dclp_strip(jxr_image_t image, int tx, int ty, int my);
55
static void recover_dclphp_strip(jxr_image_t image, int tx, int ty, int my);
56
57
int _jxr_r_TILE_DC(jxr_image_t image, struct rbitstream*str,
58
                   unsigned tx, unsigned ty)
59
0
{
60
0
    unsigned mx, my;
61
0
    unsigned mb_height;
62
0
    unsigned mb_width;
63
0
    unsigned char s0, s1, s2, s3;
64
0
    DEBUG("START TILE_DC at tile=[%u %u] bitpos=%zu\n", tx, ty, _jxr_rbitstream_bitpos(str));
65
66
    /* TILE_STARTCODE == 1 */
67
0
    s0 = _jxr_rbitstream_uint8(str); /* 0x00 */
68
0
    s1 = _jxr_rbitstream_uint8(str); /* 0x00 */
69
0
    s2 = _jxr_rbitstream_uint8(str); /* 0x01 */
70
0
    s3 = _jxr_rbitstream_uint8(str); /* reserved */
71
0
    DEBUG(" TILE_STARTCODE == %02x %02x %02x (reserved: %02x)\n", s0, s1, s2, s3);
72
73
0
    _jxr_r_TILE_HEADER_DC(image, str, 0 /* alpha */, tx, ty);
74
0
    if (ALPHACHANNEL_FLAG(image))
75
0
        _jxr_r_TILE_HEADER_DC(image->alpha, str, 1, tx, ty);
76
77
78
    /* Now form and write out all the compressed data for the
79
    tile. This involves scanning the macroblocks, and the
80
    blocks within the macroblocks, generating bits as we go. */
81
82
0
    mb_height = EXTENDED_HEIGHT_BLOCKS(image);
83
0
    mb_width = EXTENDED_WIDTH_BLOCKS(image);
84
85
0
    if (TILING_FLAG(image)) {
86
0
        mb_height = image->tile_row_height[ty];
87
0
        mb_width = image->tile_column_width[tx];
88
0
    }
89
90
0
    for (my = 0 ; my < mb_height ; my += 1) {
91
0
        _jxr_r_rotate_mb_strip(image);
92
0
        image->cur_my = my;
93
0
        for (mx = 0 ; mx < mb_width ; mx += 1) {
94
0
            _jxr_r_MB_DC(image, str, 0, tx, ty, mx, my);
95
0
            if (image->bands_present == 3 /* DCONLY */)
96
0
                _jxr_complete_cur_dclp(image, tx, mx, my);
97
0
            if (ALPHACHANNEL_FLAG(image)) {
98
0
                _jxr_r_MB_DC(image->alpha, str, 1, tx, ty, mx, my);
99
0
                if (image->alpha->bands_present == 3 /* DCONLY */)
100
0
                    _jxr_complete_cur_dclp(image->alpha, tx, mx, my);
101
0
            }
102
0
        }
103
        
104
0
        if (ALPHACHANNEL_FLAG(image))
105
0
            backup_dc_strip(image->alpha, tx, ty, my);
106
107
0
        backup_dc_strip(image, tx, ty, my);
108
0
    }
109
110
0
    _jxr_rbitstream_syncbyte(str);
111
0
    DEBUG("END TILE_DC\n");
112
113
0
    return 0;
114
0
}
115
116
int _jxr_r_TILE_LP(jxr_image_t image, struct rbitstream*str,
117
                   unsigned tx, unsigned ty)
118
0
{
119
0
    unsigned mx, my;
120
0
    unsigned plane_idx, num_planes;
121
0
    unsigned mb_height;
122
0
    unsigned mb_width;
123
0
    unsigned char s0, s1, s2, s3;
124
0
    DEBUG("START TILE_LOWPASS at tile=[%u %u] bitpos=%zu\n", tx, ty, _jxr_rbitstream_bitpos(str));
125
126
    /* TILE_STARTCODE == 1 */
127
0
    s0 = _jxr_rbitstream_uint8(str); /* 0x00 */
128
0
    s1 = _jxr_rbitstream_uint8(str); /* 0x00 */
129
0
    s2 = _jxr_rbitstream_uint8(str); /* 0x01 */
130
0
    s3 = _jxr_rbitstream_uint8(str); /* reserved */
131
0
    DEBUG(" TILE_STARTCODE == %02x %02x %02x (reserved: %02x)\n", s0, s1, s2, s3);
132
0
    if (s0 != 0x00 || s1 != 0x00 || s2 != 0x01) {
133
0
        DEBUG(" TILE_LOWPASS ERROR: Invalid marker.\n");
134
0
        return JXR_EC_ERROR;
135
0
    }
136
137
0
    _jxr_r_TILE_HEADER_LOWPASS(image, str, 0 /* alpha */, tx, ty);
138
0
    if (ALPHACHANNEL_FLAG(image))
139
0
        _jxr_r_TILE_HEADER_LOWPASS(image->alpha, str, 1, tx, ty);
140
141
    /* Now form and write out all the compressed data for the
142
    tile. This involves scanning the macroblocks, and the
143
    blocks within the macroblocks, generating bits as we go. */
144
145
0
    mb_height = EXTENDED_HEIGHT_BLOCKS(image);
146
0
    mb_width = EXTENDED_WIDTH_BLOCKS(image);
147
148
0
    if (TILING_FLAG(image)) {
149
0
        mb_height = image->tile_row_height[ty];
150
0
        mb_width = image->tile_column_width[tx];
151
0
    }
152
153
0
    num_planes = ((ALPHACHANNEL_FLAG(image)) ? 2 : 1);
154
0
    for (my = 0 ; my < mb_height ; my += 1) {
155
0
        _jxr_r_rotate_mb_strip(image);
156
0
        if (ALPHACHANNEL_FLAG(image)) {
157
0
            image->alpha->cur_my = my;
158
0
            recover_dc_strip(image->alpha, tx, ty, my);
159
0
        }
160
0
        image->cur_my = my;
161
0
        recover_dc_strip(image, tx, ty, my);
162
163
0
        for (mx = 0 ; mx < mb_width ; mx += 1)
164
0
        for (plane_idx = 0; plane_idx < num_planes; plane_idx ++) {
165
            /* The qp_index_lp table goes only into channel 0 */
166
0
            int qp_index_lp = 0;
167
0
            int ch;
168
0
            jxr_image_t plane = (plane_idx == 0 ? image : image->alpha);
169
170
0
            if (!plane->lp_use_dc_qp && plane->num_lp_qps>1) {
171
0
                qp_index_lp = _jxr_DECODE_QP_INDEX(str, plane->num_lp_qps);
172
0
                DEBUG(" DECODE_QP_INDEX(%d) --> %u\n", plane->num_lp_qps, qp_index_lp);
173
0
            }
174
0
            for (ch = 0 ; ch < plane->num_channels ; ch += 1) {
175
0
                MACROBLK_CUR_LP_QUANT(plane,ch,tx,mx) = qp_index_lp;
176
0
                DEBUG(" LP_QUANT for MBx=%d ch=%d is %d\n", mx, ch, MACROBLK_CUR_LP_QUANT(plane,ch,tx,mx));
177
0
            }
178
0
            _jxr_r_MB_LP(plane, str, 0, tx, ty, mx, my);
179
0
            if (plane->bands_present != 3 /* !DCONLY */)
180
0
                _jxr_complete_cur_dclp(plane, tx, mx, my);
181
182
0
        }
183
0
        if (ALPHACHANNEL_FLAG(image))
184
0
            backup_dclp_strip(image->alpha, tx, ty, my);
185
0
        backup_dclp_strip(image, tx, ty, my);
186
0
    }
187
188
0
    _jxr_rbitstream_syncbyte(str);
189
0
    DEBUG("END TILE_LOWPASS\n");
190
0
    return 0;
191
0
}
192
193
int _jxr_r_TILE_HP(jxr_image_t image, struct rbitstream*str,
194
                   unsigned tx, unsigned ty)
195
0
{
196
0
    unsigned mx, my;
197
0
    unsigned plane_idx, num_planes;
198
0
    unsigned mb_height;
199
0
    unsigned mb_width;
200
0
    unsigned char s0, s1, s2, s3;
201
0
    DEBUG("START TILE_HIGHPASS at tile=[%u %u] bitpos=%zu\n", tx, ty, _jxr_rbitstream_bitpos(str));
202
203
    /* TILE_STARTCODE == 1 */
204
0
    s0 = _jxr_rbitstream_uint8(str); /* 0x00 */
205
0
    s1 = _jxr_rbitstream_uint8(str); /* 0x00 */
206
0
    s2 = _jxr_rbitstream_uint8(str); /* 0x01 */
207
0
    s3 = _jxr_rbitstream_uint8(str); /* reserved */
208
0
    DEBUG(" TILE_STARTCODE == %02x %02x %02x (reserved: %02x)\n", s0, s1, s2, s3);
209
0
    if (s0 != 0x00 || s1 != 0x00 || s2 != 0x01) {
210
0
        DEBUG(" TILE_HIGHPASS ERROR: Invalid marker.\n");
211
0
        return JXR_EC_ERROR;
212
0
    }
213
214
0
    _jxr_r_TILE_HEADER_HIGHPASS(image, str, 0 /* alpha */, tx, ty);
215
0
    if (ALPHACHANNEL_FLAG(image))
216
0
        _jxr_r_TILE_HEADER_HIGHPASS(image->alpha, str, 1, tx, ty);
217
218
    /* Now form and write out all the compressed data for the
219
    tile. This involves scanning the macroblocks, and the
220
    blocks within the macroblocks, generating bits as we go. */
221
222
0
    mb_height = EXTENDED_HEIGHT_BLOCKS(image);
223
0
    mb_width = EXTENDED_WIDTH_BLOCKS(image);
224
225
0
    if (TILING_FLAG(image)) {
226
0
        mb_height = image->tile_row_height[ty];
227
0
        mb_width = image->tile_column_width[tx];
228
0
    }
229
230
0
    num_planes = ((ALPHACHANNEL_FLAG(image)) ? 2 : 1);
231
0
    for (my = 0 ; my < mb_height ; my += 1) {
232
0
        _jxr_r_rotate_mb_strip(image);
233
234
0
        if (ALPHACHANNEL_FLAG(image)) {
235
0
            image->alpha->cur_my = my;
236
0
            recover_dclp_strip(image->alpha, tx, ty, my);
237
0
        }
238
0
        image->cur_my = my;
239
0
        recover_dclp_strip(image, tx, ty, my);
240
241
0
        for (mx = 0 ; mx < mb_width ; mx += 1) 
242
0
        for (plane_idx = 0; plane_idx < num_planes; plane_idx ++) {
243
            /* The qp_index_hp table goes only into channel 0 */
244
0
            int qp_index_hp = 0;
245
0
            int ch;
246
0
            int rc;
247
0
            jxr_image_t plane = (plane_idx == 0 ? image : image->alpha);
248
0
            if (plane->num_hp_qps>1) {
249
0
                if (!plane->hp_use_lp_qp)
250
0
                    qp_index_hp = _jxr_DECODE_QP_INDEX(str, plane->num_hp_qps);
251
0
                else
252
0
                    qp_index_hp = MACROBLK_CUR_LP_QUANT(plane,0,tx,mx);
253
0
            }
254
0
            DEBUG(" HP_QP_INDEX for MBx=%d is %d\n", mx, qp_index_hp);
255
0
            for (ch = 0 ; ch < plane->num_channels ; ch += 1) {
256
0
                MACROBLK_CUR_HP_QUANT(plane,ch,tx,mx) = plane->hp_quant_ch[ch][qp_index_hp];
257
0
                DEBUG(" HP_QUANT for MBx=%d ch=%d is %d\n", mx, ch, MACROBLK_CUR_HP_QUANT(plane,ch,tx,mx));
258
0
            }
259
260
0
            rc = _jxr_r_MB_CBP(plane, str, 0, tx, ty, mx, my);
261
0
            if (rc < 0) {
262
0
                DEBUG("r_MB_CBP returned ERROR rc=%d\n", rc);
263
0
                return rc;
264
0
            }
265
0
            rc = _jxr_r_MB_HP(plane, str, 0, tx, ty, mx, my);
266
0
            if (rc < 0) {
267
0
                DEBUG("r_MB_HP returned ERROR rc=%d\n", rc);
268
0
                return rc;
269
0
            }
270
0
        }
271
0
        if (ALPHACHANNEL_FLAG(image))
272
0
            backup_hp_strip(image->alpha, tx, ty, my);
273
0
        backup_hp_strip(image, tx, ty, my);
274
0
    }
275
276
0
    _jxr_rbitstream_syncbyte(str);
277
0
    DEBUG("END TILE_HIGHPASS\n");
278
0
    return 0;
279
0
}
280
281
int _jxr_r_TILE_FLEXBITS(jxr_image_t image, struct rbitstream*str,
282
                         unsigned tx, unsigned ty)
283
0
{
284
0
    int mx, my;
285
0
    int plane_idx, num_planes;
286
0
    unsigned mb_height;
287
0
    unsigned mb_width;
288
0
    int use_num_channels;
289
0
    unsigned char s0, s1, s2, s3;
290
291
0
    DEBUG("START TILE_FLEXBITS at tile=[%u %u] bitpos=%zu\n", tx, ty, _jxr_rbitstream_bitpos(str));
292
293
    /* TILE_STARTCODE == 1 */
294
0
    s0 = _jxr_rbitstream_uint8(str); /* 0x00 */
295
0
    s1 = _jxr_rbitstream_uint8(str); /* 0x00 */
296
0
    s2 = _jxr_rbitstream_uint8(str); /* 0x01 */
297
0
    s3 = _jxr_rbitstream_uint8(str); /* reserved */
298
0
    DEBUG(" TILE_STARTCODE == %02x %02x %02x (reserved: %02x)\n", s0, s1, s2, s3);
299
0
    if (s0 != 0x00 || s1 != 0x00 || s2 != 0x01) {
300
0
        DEBUG(" TILE_FLEXBITS ERROR: Invalid marker.\n");
301
0
        return JXR_EC_ERROR;
302
0
    }
303
304
0
    image->trim_flexbits = 0;
305
0
    if (TRIM_FLEXBITS_FLAG(image)) {
306
0
        image->trim_flexbits =_jxr_rbitstream_uint4(str);
307
0
        DEBUG(" TRIM_FLEXBITS = %u\n", image->trim_flexbits);
308
0
    }
309
310
0
    use_num_channels = image->num_channels;
311
0
    if (image->use_clr_fmt == 1/*YUV420*/ || image->use_clr_fmt == 2/*YUV422*/)
312
0
        use_num_channels = 1;
313
314
    /* Now form and write out all the compressed data for the
315
    tile. This involves scanning the macroblocks, and the
316
    blocks within the macroblocks, generating bits as we go. */
317
318
0
    mb_height = EXTENDED_HEIGHT_BLOCKS(image);
319
0
    mb_width = EXTENDED_WIDTH_BLOCKS(image);
320
321
0
    if (TILING_FLAG(image)) {
322
0
        mb_height = image->tile_row_height[ty];
323
0
        mb_width = image->tile_column_width[tx];
324
0
    }
325
326
0
    num_planes = ((ALPHACHANNEL_FLAG(image)) ? 2 : 1);
327
0
    for (my = 0 ; my < (int) mb_height ; my += 1) {
328
0
        _jxr_r_rotate_mb_strip(image);
329
0
        if (ALPHACHANNEL_FLAG(image)) {
330
0
            image->alpha->cur_my = my;
331
0
            recover_dclphp_strip(image->alpha, tx, ty, my);
332
0
        }
333
0
        image->cur_my = my;
334
0
        recover_dclphp_strip(image, tx, ty, my);
335
336
0
        for (mx = 0 ; mx < (int) mb_width ; mx += 1) 
337
0
        for (plane_idx = 0; plane_idx < num_planes; plane_idx ++) {
338
0
            jxr_image_t plane = (plane_idx == 0 ? image : image->alpha);
339
0
            int channels = (plane_idx == 0 ? use_num_channels : 1);
340
0
            int rc = _jxr_r_MB_FLEXBITS(plane, str, 0, tx, ty, mx, my);
341
0
            int mbhp_pred_mode;
342
0
            int idx;
343
0
            if (rc < 0) {
344
0
                DEBUG("r_MB_FLEXBITS returned ERROR rc=%d\n", rc);
345
0
                return rc;
346
0
            }
347
348
            /* Now the HP values are complete, so run the propagation
349
            process. This involves recovering some bits of data saved
350
            by the HP tile. */
351
0
            mbhp_pred_mode = MACROBLK_CUR(plane,0,tx,mx).mbhp_pred_mode;
352
0
            for (idx = 0 ; idx < channels ; idx += 1) {
353
0
                DEBUG(" MB_FLEXBITS: propagate HP predictions in MB_FLEXBITS\n");
354
0
                _jxr_propagate_hp_predictions(plane, idx, tx, mx, mbhp_pred_mode);
355
0
            }
356
0
        }
357
0
        if (ALPHACHANNEL_FLAG(image))
358
0
            backup_hp_strip(image->alpha, tx, ty, my);
359
0
        backup_hp_strip(image, tx, ty, my);
360
0
    }
361
362
0
    _jxr_rbitstream_syncbyte(str);
363
0
    DEBUG("END TILE_FLEXBITS bitpos=%zu\n", _jxr_rbitstream_bitpos(str));
364
0
    return 0;
365
0
}
366
367
/*
368
* This function handles the special case that the FLEXBITS tile is
369
* escaped away. Do all the soft processing that is otherwise needed.
370
*/
371
int _jxr_r_TILE_FLEXBITS_ESCAPE(jxr_image_t image, unsigned tx, unsigned ty)
372
0
{
373
0
    int use_num_channels = image->num_channels;
374
0
    unsigned mb_height = EXTENDED_HEIGHT_BLOCKS(image);
375
0
    unsigned mb_width = EXTENDED_WIDTH_BLOCKS(image);
376
0
    int mx, my;
377
378
0
    DEBUG("START TILE_FLEXBITS_ESCAPE at tile=[%u %u]\n", tx, ty);
379
380
0
    if (image->use_clr_fmt == 1/*YUV420*/ || image->use_clr_fmt == 2/*YUV422*/)
381
0
        use_num_channels = 1;
382
383
0
    if (TILING_FLAG(image)) {
384
0
        mb_height = image->tile_row_height[ty];
385
0
        mb_width = image->tile_column_width[tx];
386
0
    }
387
388
0
    for (my = 0 ; my < (int) mb_height ; my += 1) {
389
0
        _jxr_r_rotate_mb_strip(image);
390
0
        image->cur_my = my;
391
0
        recover_dclphp_strip(image, tx, ty, my);
392
393
0
        for (mx = 0 ; mx < (int) mb_width ; mx += 1) {
394
            /* */
395
0
            int mbhp_pred_mode = MACROBLK_CUR(image,0,tx,mx).mbhp_pred_mode;
396
0
            int idx;
397
0
            for (idx = 0 ; idx < use_num_channels ; idx += 1) {
398
0
                DEBUG(" MB_FLEXBITS_ESCAPE: propagate HP predictions in MB_FLEXBITS\n");
399
0
                _jxr_propagate_hp_predictions(image, idx, tx, mx, mbhp_pred_mode);
400
0
            }
401
0
        }
402
0
        backup_hp_strip(image, tx, ty, my);
403
0
    }
404
405
0
    DEBUG("END TILE_FLEXBIT_ESCAPE\n");
406
0
    return 0;
407
0
}
408
409
static void backup_dc_strip(jxr_image_t image, int tx, int ty, int my)
410
0
{
411
0
    int mx;
412
0
    int use_my = my + image->tile_row_position[ty];
413
0
    int use_mx = image->tile_column_position[tx];
414
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
415
416
0
    int ch;
417
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
418
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
419
420
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
421
0
            mb[mx].data[0] = MACROBLK_CUR_DC(image,ch,tx,mx);
422
0
            DEBUG(" backup_dc_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d, DC=0x%0x8\n",
423
0
                tx, ty, mx, my, ch, mb[mx].data[0]);
424
0
        }
425
0
    }
426
0
}
427
428
static void backup_dclp_strip(jxr_image_t image, int tx, int ty, int my)
429
0
{
430
0
    int mx;
431
0
    int use_my = my + image->tile_row_position[ty];
432
0
    int use_mx = image->tile_column_position[tx];
433
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
434
435
436
0
    int format_scale = 15;
437
0
    int ch;
438
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
439
0
        format_scale = 7;
440
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
441
0
        format_scale = 3;
442
0
    }
443
444
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
445
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
446
0
        int count = ch==0? 15 : format_scale;
447
448
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
449
0
            int idx;
450
0
            mb[mx].data[0] = MACROBLK_CUR_DC(image,ch,tx,mx);
451
0
            DEBUG(" backup_dclp_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d, DC=0x%x, LP=",
452
0
                tx, ty, mx, my, ch, mb[mx].data[0]);
453
0
            for (idx = 0 ; idx < count ; idx += 1) {
454
0
                mb[mx].data[idx+1] = MACROBLK_CUR_LP(image,ch,tx,mx,idx);
455
0
                DEBUG(" 0x%x", mb[mx].data[idx+1]);
456
0
            }
457
0
            DEBUG("\n");
458
0
            mb[mx].lp_quant = MACROBLK_CUR_LP_QUANT(image,ch,tx,mx);
459
0
        }
460
0
    }
461
0
}
462
463
static void backup_hp_strip(jxr_image_t image, int tx, int ty, int my)
464
0
{
465
0
    int mx;
466
0
    int use_my = my + image->tile_row_position[ty];
467
0
    int use_mx = image->tile_column_position[tx];
468
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
469
470
471
0
    int format_scale = 16;
472
0
    int ch;
473
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
474
0
        format_scale = 8;
475
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
476
0
        format_scale = 4;
477
0
    }
478
479
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
480
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
481
0
        int count = ch==0? 16 : format_scale;
482
483
0
        if (ch == 0) {
484
            /* Backup also the hp_model_bits, which are
485
            stored only in the channel-0 blocks. */
486
0
            for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
487
0
                mb[mx].hp_model_bits[0] = MACROBLK_CUR(image,0,tx,mx).hp_model_bits[0];
488
0
                mb[mx].hp_model_bits[1] = MACROBLK_CUR(image,0,tx,mx).hp_model_bits[1];
489
0
                mb[mx].mbhp_pred_mode = MACROBLK_CUR(image,0,tx,mx).mbhp_pred_mode;
490
0
            }
491
0
        }
492
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
493
0
            int blk;
494
0
            mb[mx].data[0] = MACROBLK_CUR_DC(image,ch,tx,mx);
495
0
            DEBUG(" backup_hp_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d\n",
496
0
                tx, ty, mx, my, ch);
497
0
            for (blk = 0 ; blk < count ; blk += 1) {
498
0
                int idx;
499
0
                for (idx = 0 ; idx < 15 ; idx += 1)
500
0
                    mb[mx].data[count+15*blk+idx] = MACROBLK_CUR_HP(image,ch,tx,mx,blk,idx);
501
0
            }
502
0
            mb[mx].hp_quant = MACROBLK_CUR_HP_QUANT(image,ch,tx,mx);
503
0
        }
504
0
    }
505
0
}
506
507
static void recover_dc_strip(jxr_image_t image, int tx, int ty, int my)
508
0
{
509
0
    int mx;
510
0
    int use_my = my + image->tile_row_position[ty];
511
0
    int use_mx = image->tile_column_position[tx];
512
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
513
514
0
    int ch;
515
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
516
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
517
518
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
519
0
            MACROBLK_CUR_DC(image,ch,tx,mx) = mb[mx].data[0];
520
0
            DEBUG(" recover_dc_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d, DC=0x%0x8\n",
521
0
                tx, ty, mx, my, ch, mb[mx].data[0]);
522
0
        }
523
0
    }
524
0
}
525
526
static void recover_dclp_strip(jxr_image_t image, int tx, int ty, int my)
527
0
{
528
0
    int mx;
529
0
    int use_my = my + image->tile_row_position[ty];
530
0
    int use_mx = image->tile_column_position[tx];
531
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
532
0
    int ch;
533
534
0
    int format_scale = 15;
535
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
536
0
        format_scale = 7;
537
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
538
0
        format_scale = 3;
539
0
    }
540
541
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
542
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
543
0
        int count = ch==0? 15 : format_scale;
544
545
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
546
0
            int idx;
547
0
            MACROBLK_CUR_DC(image,ch,tx,mx) = mb[mx].data[0];
548
0
            DEBUG(" recover_dclp_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d, DC=0x%0x8, LP=\n",
549
0
                tx, ty, mx, my, ch, mb[mx].data[0]);
550
0
            for (idx = 0 ; idx < count ; idx += 1) {
551
0
                MACROBLK_CUR_LP(image,ch,tx,mx,idx) = mb[mx].data[idx+1];
552
0
                DEBUG(" 0x%x", mb[mx].data[idx+1]);
553
0
            }
554
0
            DEBUG("\n");
555
0
            MACROBLK_CUR_LP_QUANT(image,ch,tx,mx) = mb[mx].lp_quant;
556
0
        }
557
0
    }
558
0
}
559
560
static void recover_dclphp_strip(jxr_image_t image, int tx, int ty, int my)
561
0
{
562
0
    int mx;
563
0
    int use_my = my + image->tile_row_position[ty];
564
0
    int use_mx = image->tile_column_position[tx];
565
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
566
567
0
    int format_scale = 16;
568
0
    int ch;
569
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
570
0
        format_scale = 8;
571
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
572
0
        format_scale = 4;
573
0
    }
574
575
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
576
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
577
0
        int count = ch==0? 16 : format_scale;
578
579
0
        if (ch == 0) {
580
            /* Recover also the hp_model_bits, which are
581
            stored only in the channel-0 blocks. */
582
0
            for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
583
0
                MACROBLK_CUR(image,0,tx,mx).hp_model_bits[0] = mb[mx].hp_model_bits[0];
584
0
                MACROBLK_CUR(image,0,tx,mx).hp_model_bits[1] = mb[mx].hp_model_bits[1];
585
0
                MACROBLK_CUR(image,0,tx,mx).mbhp_pred_mode = mb[mx].mbhp_pred_mode;
586
0
            }
587
0
        }
588
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
589
0
            int blk;
590
0
            MACROBLK_CUR_DC(image,ch,tx,mx) = mb[mx].data[0];
591
0
            DEBUG(" recover_dclphp_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d, DC=0x%0x8, LP=\n",
592
0
                tx, ty, mx, my, ch, mb[mx].data[0]);
593
0
            for (blk = 1 ; blk < count ; blk += 1) {
594
0
                MACROBLK_CUR_LP(image,ch,tx,mx,blk-1) = mb[mx].data[blk];
595
0
                DEBUG(" 0x%x", mb[mx].data[blk]);
596
0
            }
597
598
0
            for (blk = 0 ; blk < count ; blk += 1) {
599
0
                int idx;
600
0
                for (idx = 0 ; idx < 15 ; idx += 1) {
601
0
                    int data_ptr = count+15*blk+idx;
602
0
                    MACROBLK_CUR_HP(image,ch,tx,mx,blk,idx) = mb[mx].data[data_ptr];
603
0
                }
604
0
            }
605
0
            DEBUG("\n");
606
0
            MACROBLK_CUR_LP_QUANT(image,ch,tx,mx) = mb[mx].lp_quant;
607
0
            MACROBLK_CUR_HP_QUANT(image,ch,tx,mx) = mb[mx].hp_quant;
608
0
        }
609
0
    }
610
0
}
611
612
void _jxr_frequency_mode_render(jxr_image_t image)
613
0
{
614
615
0
    int ty;
616
0
    for (ty = 0 ; ty < (int) image->tile_rows ; ty += 1) {
617
0
        int my;
618
0
        for (my = 0 ; my < (int) image->tile_row_height[ty] ; my += 1) {
619
0
            int tx;
620
0
            if (ALPHACHANNEL_FLAG(image))
621
0
                _jxr_rflush_mb_strip(image->alpha, -1, -1, my + image->alpha->tile_row_position[ty]);
622
0
            _jxr_rflush_mb_strip(image, -1, -1, my + image->tile_row_position[ty]);
623
0
            for (tx = 0 ; tx < (int) image->tile_columns ; tx += 1) {
624
0
                if (ALPHACHANNEL_FLAG(image))
625
0
                    recover_dclphp_strip(image->alpha, tx, ty, my);
626
0
                recover_dclphp_strip(image, tx, ty, my);
627
0
            }
628
0
        }
629
0
    }
630
631
0
    if (ALPHACHANNEL_FLAG(image))
632
0
        _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+0);
633
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+0);
634
    
635
0
    if (ALPHACHANNEL_FLAG(image))
636
0
        _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+1);
637
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+1);
638
    
639
0
    if (ALPHACHANNEL_FLAG(image))
640
0
        _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+2);
641
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+2);
642
643
0
    if (ALPHACHANNEL_FLAG(image))
644
0
        _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+3);
645
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+3);
646
0
}
647
648
/*
649
* $Log: r_tile_frequency.c,v $
650
* Revision 1.16 2009/05/29 12:00:00 microsoft
651
* Reference Software v1.6 updates.
652
*
653
* Revision 1.15 2009/04/13 12:00:00 microsoft
654
* Reference Software v1.5 updates.
655
*
656
* Revision 1.14 2008/03/18 21:34:04 steve
657
* Fix distributed color prediction.
658
*
659
* Revision 1.13 2008/03/05 06:58:10 gus
660
* *** empty log message ***
661
*
662
* Revision 1.12 2008/02/26 23:52:44 steve
663
* Remove ident for MS compilers.
664
*
665
* Revision 1.11 2007/11/26 01:47:15 steve
666
* Add copyright notices per MS request.
667
*
668
* Revision 1.10 2007/11/21 00:34:30 steve
669
* Rework spatial mode tile macroblock shuffling.
670
*
671
* Revision 1.9 2007/11/20 00:05:47 steve
672
* Complex handling of mbhp_pred_mode in frequency dmoe.
673
*
674
* Revision 1.8 2007/11/16 21:33:48 steve
675
* Store MB Quant, not qp_index.
676
*
677
* Revision 1.7 2007/11/16 20:03:57 steve
678
* Store MB Quant, not qp_index.
679
*
680
* Revision 1.6 2007/11/16 17:33:24 steve
681
* Do HP prediction after FLEXBITS frequency tiles.
682
*
683
* Revision 1.5 2007/11/16 00:29:06 steve
684
* Support FREQUENCY mode HP and FLEXBITS
685
*
686
* Revision 1.4 2007/11/15 17:44:13 steve
687
* Frequency mode color support.
688
*
689
* Revision 1.3 2007/11/14 23:56:17 steve
690
* Fix TILE ordering, using seeks, for FREQUENCY mode.
691
*
692
* Revision 1.2 2007/11/13 03:27:23 steve
693
* Add Frequency mode LP support.
694
*
695
* Revision 1.1 2007/11/12 23:21:55 steve
696
* Infrastructure for frequency mode ordering.
697
*
698
*/
699